SHOW:
|
|
- or go back to the newest paste.
1 | //: concurrency/DeadlockingDiningPhilosophers.java | |
2 | package concurrency; | |
3 | ||
4 | import java.util.concurrent.*; | |
5 | ||
6 | public class DeadlockingDiningPhilosophers { | |
7 | public static void main(String[] args) throws Exception { | |
8 | int ponder = 5; | |
9 | if(args.length > 0) | |
10 | ponder = Integer.parseInt(args[0]); | |
11 | int size = 5; | |
12 | if(args.length > 1) | |
13 | size = Integer.parseInt(args[1]); | |
14 | ExecutorService exec = Executors.newCachedThreadPool(); | |
15 | Chopstick[] sticks = new Chopstick[size]; | |
16 | LinkedBlockingQueue<Chopstick> bin = new LinkedBlockingQueue<Chopstick>(); | |
17 | for(int i = 0; i < size; i++) | |
18 | sticks[i] = new Chopstick(); | |
19 | for(int i = 0; i < size; i++) | |
20 | exec.execute(new Philosopher( | |
21 | sticks[i], sticks[(i+1) % size], bin, i, ponder)); | |
22 | if(args.length == 3 && args[2].equals("timeout")) | |
23 | TimeUnit.SECONDS.sleep(5); | |
24 | else { | |
25 | System.out.println("Press 'Enter' to quit"); | |
26 | System.in.read(); | |
27 | } | |
28 | exec.shutdownNow(); | |
29 | } | |
30 | } | |
31 | ||
32 | //: concurrency/Philosopher.java | |
33 | // A dining philosopher | |
34 | package concurrency; | |
35 | ||
36 | import java.util.concurrent.*; | |
37 | import java.util.*; | |
38 | import static util.Print.*; | |
39 | ||
40 | public class Philosopher implements Runnable { | |
41 | private BlockingQueue<Chopstick> bin; | |
42 | private Chopstick left; | |
43 | private Chopstick right; | |
44 | private final int id; | |
45 | private final int ponderFactor; | |
46 | private Random rand = new Random(47); | |
47 | private void pause() throws InterruptedException { | |
48 | if(ponderFactor == 0) return; | |
49 | TimeUnit.MILLISECONDS.sleep( | |
50 | rand.nextInt(ponderFactor * 250)); | |
51 | } | |
52 | public Philosopher(Chopstick left, Chopstick right, BlockingQueue<Chopstick> bin, | |
53 | int ident, int ponder) { | |
54 | this.left = left; | |
55 | this.right = right; | |
56 | this.bin = bin; | |
57 | id = ident; | |
58 | ponderFactor = ponder; | |
59 | } | |
60 | public void run() { | |
61 | try { | |
62 | print(this + " " + "thinking"); | |
63 | pause(); | |
64 | // Philosopher becomes hungry | |
65 | print(this + " " + "grabbing right"); | |
66 | right.take(); | |
67 | print(this + " " + "grabbing left"); | |
68 | left.take(); | |
69 | print(this + " " + "eating"); | |
70 | pause(); | |
71 | right.drop(); | |
72 | left.drop(); | |
73 | print("putting left to bin."); bin.put(left); | |
74 | while(!Thread.interrupted()) { | |
75 | print(this + " " + "thinking"); | |
76 | pause(); | |
77 | // Philosopher becomes hungry | |
78 | print(this + " " + "grabbing right from bin"); | |
79 | right = bin.take(); | |
80 | print(this + " " + "grabbing left from bin"); | |
81 | left = bin.take(); | |
82 | print(this + " " + "eating"); | |
83 | pause(); | |
84 | print(this + " " + "putting right to bin "); bin.put(right); | |
85 | print(this + " " + "putting left to bin "); bin.put(left); | |
86 | } | |
87 | } catch(InterruptedException e) { | |
88 | print(this + " " + "exiting via interrupt"); | |
89 | } | |
90 | } | |
91 | public String toString() { return "Philosopher " + id; } | |
92 | } ///:~ | |
93 | ||
94 | //: concurrency/Chopstick.java | |
95 | package concurrency; | |
96 | ||
97 | public class Chopstick { | |
98 | private boolean taken = false; | |
99 | public synchronized | |
100 | void take() throws InterruptedException { | |
101 | while(taken) | |
102 | wait(); | |
103 | taken = true; | |
104 | } | |
105 | public synchronized void drop() { | |
106 | taken = false; | |
107 | notifyAll(); | |
108 | } | |
109 | } ///:~ |