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?