该问题涉及到五个哲学家,他们交替地进行思考和进餐。他们分别坐在位于一个圆形餐桌周围的五把椅子上,圆桌中央是一碗米饭,餐桌上共有五根筷子,分别摆放在每两个相邻座位的中间。
当哲学家思考时,他不与其他人交谈。当哲学家饥饿时,他将拿起和他相邻的两根筷子进行进餐,但他很可能仅拿到一根,此时旁边的另一根正在他邻居的手中。只有他同时拿到两根筷子时他才能开始进餐。完成进餐后,他将两根筷子分别放回原位,然后再次开始思考。
下面是哲学家进餐问题的Java实现的代码,涉及到线程:
1/*
2 * 创建日期 2006-4-5
3 */
4package threadDemo;
5
6class ChopStick { //筷子类
7 boolean available;
8 ChopStick() {
9 available=true; //可以拿起
10 }
11 public synchronized void takeup() { //拿起动作
12 while(!available) {
13 try {
14 wait();
15 System.out.println("哲学家等待另一根筷子");
16 } catch(InterruptedException e) { }
17 }
18 available=false;
19 }
20
21 public synchronized void putdown() { //放下动作
22 available=true;
23 notify();
24 }
25}
26
27
28class Philosopher extends Thread { //哲学家类
29 ChopStick left, right;
30 int philo_num; //哲学家编号
31
32 Philosopher (int num, ChopStick c1, ChopStick c2) {
33 philo_num = num;
34 left = c1;
35 right = c2;
36 setDaemon(true); //此函数设true时,关闭主线程,子线程也跟着关闭
37 //否则,关闭主线程,子线程继续执行
38 }
39
40 public void eat() {
41 left.takeup();
42 right.takeup();
43 System.out.println("哲学家 " + (philo_num + 1) + " 正在进餐");
44 }
45
46 public void think() {
47 left.putdown();
48 right.putdown();
49 System.out.println("哲学家 " + (philo_num + 1) + " 正在思考");
50 }
51
52 public void run() {
53 while(true) {
54 eat();
55
56 try {
57 sleep(2000); //吃的时间是2秒
58 }
59 catch (InterruptedException e) {}
60
61 think();
62
63 try {
64 sleep(2000); //思考的时间也是2秒
65 }
66 catch (InterruptedException e) {}
67 }
68 }
69}
70
71
72public class Dining {
73 static ChopStick[] chopsticks = new ChopStick[5];
74 static Philosopher[] philos = new Philosopher[5];
75
76 public static void main(String args[]) {
77 for (int i = 0; i < 5; i ++ ) {
78 chopsticks[i] = new ChopStick();
79 }
80
81 for (int i = 0; i < 5; i ++ ) {
82 philos[i] = new Philosopher(i, chopsticks[i], chopsticks[(i + 1) % 5]);
83 }
84
85 for (int i = 0; i < 5; i ++) {
86 philos[i].start();
87 }
88
89 try
90 {
91 System.in.read(); //wait until Enter is pressed
92 for (int i = 0; i < 5; i ++) {
93
94 philos[i].interrupt();
95 }
96 }
97 catch(Exception e)
98 { }
99 }
100}
101
102
103
2 * 创建日期 2006-4-5
3 */
4package threadDemo;
5
6class ChopStick { //筷子类
7 boolean available;
8 ChopStick() {
9 available=true; //可以拿起
10 }
11 public synchronized void takeup() { //拿起动作
12 while(!available) {
13 try {
14 wait();
15 System.out.println("哲学家等待另一根筷子");
16 } catch(InterruptedException e) { }
17 }
18 available=false;
19 }
20
21 public synchronized void putdown() { //放下动作
22 available=true;
23 notify();
24 }
25}
26
27
28class Philosopher extends Thread { //哲学家类
29 ChopStick left, right;
30 int philo_num; //哲学家编号
31
32 Philosopher (int num, ChopStick c1, ChopStick c2) {
33 philo_num = num;
34 left = c1;
35 right = c2;
36 setDaemon(true); //此函数设true时,关闭主线程,子线程也跟着关闭
37 //否则,关闭主线程,子线程继续执行
38 }
39
40 public void eat() {
41 left.takeup();
42 right.takeup();
43 System.out.println("哲学家 " + (philo_num + 1) + " 正在进餐");
44 }
45
46 public void think() {
47 left.putdown();
48 right.putdown();
49 System.out.println("哲学家 " + (philo_num + 1) + " 正在思考");
50 }
51
52 public void run() {
53 while(true) {
54 eat();
55
56 try {
57 sleep(2000); //吃的时间是2秒
58 }
59 catch (InterruptedException e) {}
60
61 think();
62
63 try {
64 sleep(2000); //思考的时间也是2秒
65 }
66 catch (InterruptedException e) {}
67 }
68 }
69}
70
71
72public class Dining {
73 static ChopStick[] chopsticks = new ChopStick[5];
74 static Philosopher[] philos = new Philosopher[5];
75
76 public static void main(String args[]) {
77 for (int i = 0; i < 5; i ++ ) {
78 chopsticks[i] = new ChopStick();
79 }
80
81 for (int i = 0; i < 5; i ++ ) {
82 philos[i] = new Philosopher(i, chopsticks[i], chopsticks[(i + 1) % 5]);
83 }
84
85 for (int i = 0; i < 5; i ++) {
86 philos[i].start();
87 }
88
89 try
90 {
91 System.in.read(); //wait until Enter is pressed
92 for (int i = 0; i < 5; i ++) {
93
94 philos[i].interrupt();
95 }
96 }
97 catch(Exception e)
98 { }
99 }
100}
101
102
103
运行结果:
哲学家 1 正在进餐
哲学家 3 正在进餐
哲学家等待另一根筷子
哲学家 3 正在思考
哲学家等待另一根筷子
哲学家 5 正在进餐
哲学家等待另一根筷子
哲学家 2 正在进餐
哲学家 1 正在思考
哲学家 5 正在思考
哲学家 2 正在思考
哲学家等待另一根筷子
...............