Why does this code have deadlock? I've broken the circular wait, so it should't happen (dining philosophers)

70 Views Asked by At

Main.java:

package esempio2;

public class Main {

    public static void main(String args[]){
        int numFilosofi = 5;
        Forchetta forchette[] = new Forchetta[numFilosofi];
        Filosofo filosofi[] = new Filosofo[numFilosofi];

        for(int i=0;i<numFilosofi;++i){
            forchette[i] = new Forchetta(i);
        }

        int sxForkIndex,dxForkIndex;
        for(int i=0;i<numFilosofi;++i){
            sxForkIndex = i-1;
            dxForkIndex = i;
            if (i==0)
                sxForkIndex = numFilosofi-1;
            filosofi[i] = new Filosofo(forchette[sxForkIndex],forchette[dxForkIndex],i);
            filosofi[i].start();
            
        }
    }

}

Filosofo.java (it should break the circular wait because I am making the thread 0 doing something different!):

package esempio2;

public class Filosofo extends Thread{
    int id;
    Forchetta forchettaSx;
    Forchetta forchettaDx;

    public Filosofo(Forchetta forchettaSx, Forchetta forchettaDx, int id){
        this.id = id;
        this.forchettaSx = forchettaSx;
        this.forchettaDx = forchettaDx;
    }

    @Override
    public void run(){

        while(true){
            if (this.id==0){ // THIS SHOULD BREAK THE CIRCULAR WAIT
                this.forchettaSx.prendiFork(this.id);
                System.out.println("Il filosofo num "+this.id+" ha preso forchetta sx num "+this.forchettaSx.id);
                this.forchettaDx.prendiFork(this.id);
                System.out.println("Il filosofo num "+this.id+" ha preso forchetta dx num "+this.forchettaDx.id);
                this.forchettaSx.posaFork(this.id);
                System.out.println("Il filosofo num "+this.id+" ha posato forchetta sx num "+this.forchettaSx.id);
                this.forchettaDx.posaFork(this.id);
                System.out.println("Il filosofo num "+this.id+" ha posato forchetta dx num "+this.forchettaDx.id);
            } else{
                this.forchettaDx.prendiFork(this.id);   
                System.out.println("Il filosofo num "+this.id+" ha preso forchetta dx num "+this.forchettaDx.id);
                this.forchettaSx.prendiFork(this.id);
                System.out.println("Il filosofo num "+this.id+" ha preso forchetta sx num "+this.forchettaSx.id);
                this.forchettaDx.posaFork(this.id);
                System.out.println("Il filosofo num "+this.id+" ha posato forchetta Dx num "+this.forchettaDx.id);
                this.forchettaSx.posaFork(this.id);
                System.out.println("Il filosofo num "+this.id+" ha posato forchetta Sx num "+this.forchettaSx.id);
            }
        }
    }
}

Forchetta.java

package esempio2;

public class Forchetta {
    int id;
    boolean libera = true;

    public Forchetta(int id){
        this.id=id;
    }

    public synchronized void prendiFork(int idFilosofo){
        while(libera==false){
            try{
                System.out.println("Il filosofo num "+idFilosofo+" NON puo prendere forchetta num "+this.id);
                wait();
            } catch(InterruptedException e){
                e.printStackTrace();
            }
        }
        this.libera=false;

    }

    public synchronized void posaFork(int idFilosofo){
        this.libera=true;
        notifyAll();
    }
}

Basically, if I remove the if statement and make all the threads do the same thing, it breaks immediately and goes deadlock. However, If I add that if, it doesn't freeze immediately, but only after some minutes. Why does this happen?

If I write if (this.id%2 == 0) instead of if (this.id==0), it seems not to freeze! Why?

0

There are 0 best solutions below