问题
问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条。哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿到两只筷子才能吃饭。上述问题会产生死锁的情况,当5个哲学家都拿起自己右手边的筷子,准备拿左手边的筷子时产生死锁现象。
代码
代码逻辑:
多少个哲学家,就有多少个筷子,判断哲学家左右两边的筷子是否正在使用,如果正在被使用,则将当前哲学家阻塞起来
哲学家:
public class philosopher extends Thread{
private String id;
private Chopsticks chopsticks;
public philosopher(String id, Chopsticks chopsticks){
this.id = id;
super.setName(id);
this.chopsticks = chopsticks;
}
public void eat(){
System.out.println("哲学家-" + id + " is eating");
try {
sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void think(){
System.out.println("哲学家-" + id + " is thinking");
try {
sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
//think();
chopsticks.take();
eat();
chopsticks.put();
}
}
筷子类:
class Chopsticks {
private boolean[] used;
private int count;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public Chopsticks(int count) {
this.count = count;
used = new boolean[count];
for (int i = 0; i < used.length; i++) {
used[i] = false;
}
}
public void take() {
lock.lock();
try {
int i = Integer.parseInt(Thread.currentThread().getName());
//只要左边或右边的筷子被拿走了,就一直阻塞
while (used[i] || used[ (i+1)%count ]) {
condition.await();
}
System.out.println("take: " + i + ", " + (i+1)%count);
used[i] = true;
used[ (i+1)%count ] = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void put() {
lock.lock();
try {
int i = Integer.parseInt(Thread.currentThread().getName());
used[i] = false;
used[ (i+1)%count ] = false;
//唤醒所有阻塞的哲学家
condition.signalAll();
System.out.println("put: " + i + ", " + (i+1)%count);
} finally {
lock.unlock();
}
}
}
测试类:
class Test{
public static void main(String[] args) {
Chopsticks chopsticks = new Chopsticks(5);
for (int i = 0; i < 5; i++) {
new philosopher(i+"", chopsticks).start();
}
}
}
结果:
take: 0, 1
take: 2, 3
哲学家-2 is eating
哲学家-0 is eating
put: 0, 1
put: 2, 3
take: 1, 2
哲学家-1 is eating
take: 3, 4
哲学家-3 is eating
put: 3, 4
put: 1, 2
take: 4, 0
哲学家-4 is eating
put: 4, 0