TransWikia.com

¿Es necesario el uso de 'volatile' en estas dos variables de instancia? (Algoritmo de la Panadería)

Stack Overflow en español Asked by rmoret on September 24, 2020

Soy estudiante de Informática, y ahora mismo me encuentro estudiando una asignatura sobre Concurrencia.
Mi duda viene cuando en un código de ejemplo acerca de una explicación sobre el uso de Exclusión mutua con más de dos hebras mediante el Algoritmo de la Panadería, veo que las variables de instancia de la clase Panadería no llevan la palabra clave volatile, lo que a mi entender quiere decir que cada una de las hebras podría tener su propia copia de esta variable, y no utilizar una en común para todas, lo que creo que podría llevar a un error en la ejecución del código.
Es por esto que quería preguntar si se trata de un error en el código de ejemplo, o simplemente se me pasa algún dato que no tengo en cuenta.

Clase Panadería.

public class Panaderia {
  private int[] turno;
  private boolean[] pidiendoTurno;
  
  public Panaderia(int N){
    turno = new int[N];
    pidiendoTurno = new boolean[N];
  }

  public void cogeTurno(int id){
    pidiendoTurno[id] = true;
    int max = 0;
    for (int i = 0; i<turno.length; i++)
      if (max<turno[i]) max=turno[i];
    turno[id] = max + 1;
    pidiendoTurno[id] = false;
  }

  private boolean meToca(int id,int i){
    if (turno[i] > 0 && turno[i] < turno[id])
      return false;
    else if (turno[i] == turno[id] && i < id)
      return false;
    return true;
  }

  public void esperoTurno(int id){
    for (int i = 0; i<turno.length; i++){
      while (pidiendoTurno[i])Thread.yield();
      while (!meToca(id,i)) Thread.yield();
    }
  }

  public void salePanaderia(int id){
    turno[id] = 0;
  }
}

Clase Cliente.

class Cliente extends Thread{
  private int id;
  private Panaderia pan;
  
  public Cliente(int id,Panaderia pan){
    this.id = id; this.pan = pan;
  }

  public void run(){
    pan.cogeTurno(id);
    pan.esperaTurno(id);
    // el cliente id es atendido por el dependiente
    pan.salePanaderia(id);
    // el cliente id sale de la panadería
  }
}

En resumen, mi pregunta es si las variables de instancia de la clase Panadería, turno y pidiendoTurno deberían ser volátiles o son correctas así como están.

Eso es todo, muchísimas gracias y un saludo.

One Answer

Es una buena pregunta... y la respuesta es que no es necesario en este caso. Veamos el porqué:

De la documentación de Oracle leemos:

volatile (...) keyword used in variable declarations that specifies that the variable is modified asynchronously by concurrently running threads.

... palabra reservada usada en la declaración de variables que especifica que la variable es modificada asíncronamente por hilos concurrentes.

Esto significa que si modificas la variable, te conviene que ésta sea volatile. Pero en tu código las variables ¡no se modifican! Es decir, nunca se asigna un nuevo valor, un nuevo array, a las variables turno o pidiendoTurno. Es el array ya asignado el que recibe cambios, pero el objeto es siempre el mismo.

Correct answer by Pablo Lozano on September 24, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP