Deadlocks

Philosophes


prend la fourchette à gauche
prend la fourchette à droite
mange pendant un certain temps
met les deux fourchettes à la table
pense 
pendant un certain temps

 

class Philosopher extends Thread{
Fork leftFork, rightFork;
Philosopher(String name,Fork left, Fork right){
super.setName(name);
leftFork=left;
rightFork=right;
start();
}
public void run(){
for(int i=0;i<2;i++){
leftFork.take();
System.out.println(getName()+" look for the second fork ");
try {
sleep((int)(Math.random()*2));
} catch (InterruptedException e){}

rightFork.take();
System.out.println(getName()+" eating ");
try {
sleep((int)(Math.random()*1000));
} catch (InterruptedException e){}
System.out.println(getName()+" poses the forks - thinking");
leftFork.pose();
rightFork.pose();
try {
sleep((int)(Math.random()*1000));
} catch (InterruptedException e1){}
}
System.out.println(getName()+" stop dinning");
}
}
class Fork{
private boolean taken;
private String name;
Fork(String name){
taken = false;
this.name=name;
}
synchronized void take(){
while(taken){
System.out.println(Thread.currentThread().getName()+" waiting for "+name);
try{ wait(); }
catch(InterruptedException e){
System.err.println(e);
}
}
System.out.println(Thread.currentThread().getName()+" take "+name);
taken = true;
}
synchronized void pose(){
taken = false;
notify();
}
public String toString(){
return name;
}
}
class Dinner{
public static void main(String arg[]){
int number=5;
Fork fk[]= new Fork[number];
for(int i=0;i<number;i++){
fk[i]= new Fork("fork "+i);
}
for(int i=0; i<number;i++){
new Philosopher("P"+(i+1),fk[i],fk[(i+1)%number]);
}
}
}
P1 take fork 0
P1 look for the second fork
P2 take fork 1
P2 look for the second fork
P3 take fork 2
P3 look for the second fork
P4 take fork 3
P4 look for the second fork
P5 take fork 4
P5 look for the second fork


L'approche le plus souvent utilisée pour éviter le deadlock est introduction une ordre prioritaire dans l'utilisation des resources. 

 

 

 



 

 

La deuxième approche modifie le comportement des threads. Quand le philosophe constate que la fourchette n'est pas libre (exception est générée) se retire en laissant les fourchettes pour un certain temps avant de réessayer de les prendre.



public class TakenExc extends Exception{
}
class Philosopher extends Thread{
String name;
Fork leftFork, rightFork;
Philosopher(String name,Fork left, Fork right){
this.name=name;
super.setName(name);
leftFork=left;
rightFork=right;
}
public void run(){
for(int i=0;i<2;i++){
do {
try {
leftFork.take(this);
}catch (TakenExc te) {
try {
sleep((int)(Math.random()*600));
} catch (InterruptedException e){}
continue;
}
System.out.println(name+" look for the second fork ");
try {
sleep((int)(Math.random()*2));
} catch (InterruptedException e){}

try {
rightFork.take(this);
}catch (TakenExc te) {
leftFork.pose();
System.out.println(name+" pose waiting "+leftFork);
try {
sleep((int)(Math.random()*600));
} catch (InterruptedException e){}
continue;
}
break;
}while(true);
System.out.println(name+" eating ");
try {
sleep((int)(Math.random()*1000));
} catch (InterruptedException e){}
System.out.println(name+" poses the forks - thinking");
leftFork.pose();
rightFork.pose();
try {
sleep((int)(Math.random()*1000));
} catch (InterruptedException e1){}
}
System.out.println(name+" stop dinning");
}
public String toString(){
return name;
}
}
class Fork{
private boolean taken;
String name;
Fork(String name){
taken = false;
this.name=name;
}
synchronized void take(Philosopher p)throws TakenExc{
if(taken){
throw new TakenExc();
}
System.out.println(p+" take "+name);
taken = true;
}
synchronized void pose(){
taken = false;
notify();
}
boolean canTake(){
if (!taken)return true;
else return false;
}
public String toString(){
return name;
}
}
class Dinner{
public static void main(String arg[]){
int number=5;
Philosopher ph[]= new Philosopher[number];
Fork fk[]= new Fork[number];
for(int i=0;i<number;i++){
fk[i]= new Fork("fork "+i);
}
for(int i=0; i<number;i++){
ph[i] = new Philosopher("P"+(i+1),fk[i],fk[(i+1)%number]);
ph[i].start();
}
}
}