My Five Philosophers are all eating at the same time, why?

This is the class philosopher

public class Filosofo implements Runnable{

    public String nome = null;
    public static Bacchetta[] bacchette = new Bacchetta[5]; //this should be the resource
    public Bacchetta bacchettaDX; //right resource
    public Bacchetta bacchettaSX; //left resource
    public static int indice = 0;

    public int x[] = {};
    public int y[] = {};

    public JButton filosofo = new JButton();  //Button associated to the philos.

    public Filosofo(String nome, int SX, int DX){
        indice++;
        for(int i = 0; i<5; i++){
            bacchette[i] = new Bacchetta();
        }
        this.nome = nome;
        this.bacchettaSX = bacchette[SX];
        this.bacchettaDX = bacchette[DX]; 
    }

    @Override
    public synchronized void  run() {
        Random r = new Random();
        int random;

        while(true){
            random = (int) r.nextInt(100);
            pensa(5000);
            random = (int) r.nextInt(100);
            mangia(5000);

        }
    }


    //the method mangia means the phil. is eating, so has both chopsticks
    public synchronized void mangia(int tempo){

        do{
        if(!bacchettaSX.isOccupied){
            bacchettaSX.isOccupied = true;
            bacchettaSX.setChiOccupa(this.nome);
        }
        if(!bacchettaDX.isOccupied){
            bacchettaDX.isOccupied = true;
            bacchettaDX.setChiOccupa(this.nome);
        }
        }while(bacchettaSX.getChiOccupa().compareTo(this.nome) != 0 && bacchettaDX.getChiOccupa().compareTo(this.nome) != 0);

        this.filosofo.setBackground(Color.GREEN);
        try {
            sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Filosofo.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println("\t\t\t" + this.nome + " sta mangiando");
        int a = 0;
        /*for(long i = 0; i<1000000000; i++){
            a++;
        }*/



        bacchettaSX.isOccupied = false;
        bacchettaDX.isOccupied = false;
        bacchettaSX.setChiOccupa(null);
        bacchettaDX.setChiOccupa(null);

        System.out.println("\t\t\t\t\t\t" + this.nome + " ha finito di mangiare");
        this.filosofo.setBackground(Color.BLUE);

    }
    //the method pensa means the philosopher is no longer eating
    public void pensa(int tempo){
        System.out.println(this.nome + " sta ponderando");
        try {
            sleep(tempo);
        } catch (InterruptedException ex) {
            Logger.getLogger(Filosofo.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

}

It's supposed to print out in the terminal what's doing what, the problem is that they should eat one by one or in the best scenario maximum two philosophers. However, they eat all together. The synchronization is not doing what it's supposed to be doing. Where is the problem?

Upvotes: 2

Views: 147

Answers (1)

JP Moresmau
JP Moresmau

Reputation: 7403

Your code block

for(int i = 0; i<5; i++){
    bacchette[i] = new Bacchetta();
}

Initializes the static array each time you create a new philosopher, so they all end up with different bachettaSX and bachettaDX. Initialize it once in a static code block outside of the constructor.

static {
  for(int i = 0; i<5; i++){
    bacchette[i] = new Bacchetta();
  }
}

Upvotes: 4

Related Questions