一、问题分析
大家都先拿左手筷子,那大家都吃不了饭(一把筷子相当于一把锁,都等待右手锁释放)
继续分析:只要有一人同时拿到左右手筷子就可以解决这个问题,他吃了放下边上人再吃。
方案:引入一个左撇子。四个人拿左边的,一个人拿右边的。有一个人必然双手持有筷子。(仔细缕缕)
如图4哲学家先右手
(1)4没抢到(就会阻塞,一直尝试右手拿筷子),则其他都是左手拿到了,0号右手边的筷子一直没人拿,这个时候0号拿到右手先吃,其他人等着,0吃完放下筷子,1吃,以此类推都吃了。
(2)4号先手抢到了,3干瞪眼,其他人都左手拿到了,这个时候0、4中间有一双闲置的,随便谁抢到都可以,吃完解锁大家都吃。
这个时候有个问题,五个人依次吃效率太低了,所以引入一半左撇子,就可以提高效率
二、代码如下
public class Chopsticks {
}
public class Philosopher implements Runnable{
public Chopsticks left;
public Chopsticks right;
public Integer num;
public Philosopher(Chopsticks left, Chopsticks right,Integer num) {
this.left = left;
this.right = right;
this.num=num;
}
@Override
public void run() {
int i = num%2;
if(i==1){
synchronized (left){
sleep(3000);
synchronized(right){
sleep(3000);
System.out.println("吃完了"+Thread.currentThread().getName());
}
}
}else {
synchronized (right){
sleep(3000);
synchronized(left){
sleep(3000);
System.out.println("吃完了"+Thread.currentThread().getName());
}
}
}
}
public static void sleep(long millis){
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Chopsticks chopsticks0 = new Chopsticks();
Chopsticks chopsticks1 = new Chopsticks();
Chopsticks chopsticks2 = new Chopsticks();
Chopsticks chopsticks3 = new Chopsticks();
Chopsticks chopsticks4 = new Chopsticks();
Philosopher philosopher0 = new Philosopher(chopsticks0, chopsticks1,0);
Philosopher philosopher1 = new Philosopher(chopsticks1, chopsticks2,1);
Philosopher philosopher2 = new Philosopher(chopsticks2, chopsticks3,2);
Philosopher philosopher3 = new Philosopher(chopsticks3, chopsticks4,3);
Philosopher philosopher4 = new Philosopher(chopsticks4, chopsticks0,4);
Thread thread0 = new Thread(philosopher0);
thread0.setName("哲学0");
Thread thread1 = new Thread(philosopher1);
thread1.setName("哲学1");
Thread thread2 = new Thread(philosopher2);
thread2.setName("哲学2");
Thread thread3 = new Thread(philosopher3);
thread3.setName("哲学3");
Thread thread4 = new Thread(philosopher4);
thread4.setName("哲学4");
thread0.start();
thread2.start();
thread3.start();
thread4.start();
thread1.start();
}