首页 > 代码库 > 《Cracking the Coding Interview》——第16章:线程与锁——题目3

《Cracking the Coding Interview》——第16章:线程与锁——题目3

2014-04-27 19:26

题目:哲学家吃饭问题,死锁问题经典模型(专门用来黑哲学家的?)。

解法:死锁四条件:1. 资源互斥。2. 请求保持。3. 非抢占。4. 循环等待。所以,某砖家拿起一只筷子后如果发现没有另一只了,就必须把手里这只筷子放下,这应该是通过破坏“请求保持”原则来防止死锁产生,请求资源失败时,连自己的资源也进一步释放,然后在下一轮里继续请求,直到成功执行。

代码:

 1 // This is the class for chopsticks.
 2 import java.util.concurrent.locks.Lock;
 3 import java.util.concurrent.locks.ReentrantLock;
 4 
 5 public class Chopstick {
 6     private Lock lock;
 7     
 8     public Chopstick() {
 9         lock = new ReentrantLock();
10     }
11     
12     public boolean pickUp() {
13         return lock.tryLock();
14     }
15     
16     public void putDown() {
17         lock.unlock();
18     }
19 }
20 
21 //------------------------------------I‘m a delimiter------------------------------------
22 // This is the class for philosophers.
23 import java.util.Vector;
24 
25 public class Philosopher extends Thread {
26     private Chopstick left;
27     private Chopstick right;
28     private int id;
29     int appetite;
30 
31     final int FULL_APPETITE = 10;
32 
33     public Philosopher(Chopstick left, Chopstick right, int id) {
34         // TODO Auto-generated constructor stub
35         appetite = 0;
36         this.left = left;
37         this.right = right;
38         this.id = id;
39     }
40 
41     private boolean pickUp() {
42         if (!left.pickUp()) {
43             return false;
44         }
45         if (!right.pickUp()) {
46             left.putDown();
47             return false;
48         }
49         return true;
50     }
51 
52     private void putDown() {
53         left.putDown();
54         right.putDown();
55     }
56 
57     public boolean eat() {
58         while (appetite < FULL_APPETITE) {
59             if (!pickUp()) {
60                 return false;
61             }
62             System.out.println(id + ":chew~");
63             ++appetite;
64             putDown();
65         }
66         return appetite == FULL_APPETITE;
67     }
68 
69     @Override
70     public void run() {
71         // TODO Auto-generated method stub
72         super.run();
73         while (!eat()) {
74             // Not full yet.
75         }
76     }
77 
78     public static void main(String[] args) {
79         final int n = 6;
80         Vector<Chopstick> chopsticks = new Vector<Chopstick>();
81         Vector<Philosopher> philosophers = new Vector<Philosopher>();
82 
83         for (int i = 0; i < n; ++i) {
84             chopsticks.add(new Chopstick());
85         }
86         for (int i = 0; i < n; ++i) {
87             philosophers.add(new Philosopher(chopsticks.elementAt(i),
88                     chopsticks.elementAt((i + 1) % n), i + 1));
89         }
90         
91         for (int i = 0; i < n; ++i) {
92             philosophers.elementAt(i).start();
93         }
94     }
95 }