问题描述:
一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条。哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿到两只筷子才能吃饭。上述问题会产生死锁的情况,当5个哲学家都拿起自己右手边的筷子,准备拿左手边的筷子时产生死锁现象。
试着用多线程的形式防止死锁的出现,让每一位哲学家都顺利吃上饭。
(这是当初2019年秋招恒生电子的最后一道编程题,诶当初没答好,现在又复习到这个知识点,再来补一下吧,大家一定要自己动手写啊!!,当初确实是卡在了最后一名哲学家身边筷子编号的问题,一直很纠结,这里用了fork[i]||fork[(i+1)%5]来判断是否wait,确实是秒~~)
哲学家类:
public class Philosopher implements Runnable {
private Fork fork;
public Philosopher(Fork fork) {
this.fork = fork;
}
@Override
public void run() {
try {
System.out.println("哲学家" + Thread.currentThread().getName() + "进入思考");
Thread.sleep(1000);
System.out.println("哲学家" + Thread.currentThread().getName() + "思考完了,准备拿起筷子");
fork.takeFork();
System.out.println("哲学家" + Thread.currentThread().getName() + "拿起了筷子,恰饭咯");
Thread.sleep(1000);
fork.putFork();
System.out.println("哲学家" + Thread.currentThread().getName() + "恰完了,放下了筷子");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
Fork fork = new Fork();
Philosopher p0 = new Philosopher(fork);
Philosopher p1 = new Philosopher(fork);
Philosopher p2 = new Philosopher(fork);
Philosopher p3 = new Philosopher(fork);
Philosopher p4 = new Philosopher(fork);
new Thread(p0, "0").start();
new Thread(p1, "1").start();
new Thread(p2, "2").start();
new Thread(p3, "3").start();
new Thread(p4, "4").start();
}
}
筷子类:
public class Fork {
boolean fork[] = { false, false, false, false, false };
public synchronized void takeFork() {
String s = Thread.currentThread().getName();
int i = Integer.parseInt(s);
while (fork[i] || fork[(i + 1) % 5]) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
fork[i] = true;
fork[(i + 1) % 5] = true;
}
public synchronized void putFork() {
String s = Thread.currentThread().getName();
int i = Integer.parseInt(s);
fork[i] = false;
fork[(i + 1) % 5] = false;
notifyAll();
}
}
网友评论