我的五个哲学家都在同一时间吃东西,为什么?

时间:2015-05-11 19:16:29

标签: java multithreading dining-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);
        }

    }

}

它应该在终端打印出什么在做什么,问题是他们应该一个接一个吃,或者在最好的场景中最多吃两个哲学家。然而,他们一起吃。同步没有做它应该做的事情。问题在哪里?

1 个答案:

答案 0 :(得分:4)

您的代码块

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

每次创建一个新的哲学家时都会初始化静态数组,所以他们最终都会得到不同的bachettaSX和bachettaDX。 在构造函数之外的静态代码块中初始化一次。

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