-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPhaserDemo.java
More file actions
117 lines (106 loc) · 4.3 KB
/
Copy pathPhaserDemo.java
File metadata and controls
117 lines (106 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package Phase7_Concurrency.Multithreading;
import java.util.concurrent.Phaser;
/**
* Phaser (Java 7+)
* ----------------
* The flexible cousin of CyclicBarrier and CountDownLatch. A Phaser:
* <p>
*
* - Has a varying number of REGISTERED parties (register / arriveAndDeregister).
* - Has a PHASE counter that increases each round.
* - Lets parties signal arrival with several methods:
* <p>
*
* arriveAndAwaitAdvance() - "I'm here; wait for the rest"
* arrive() - "I'm here; don't wait" (returns the phase)
* arriveAndDeregister() - "I'm here; drop me from the pool"
* awaitAdvance(phase) - block until we move past `phase`
* <p>
*
* - Supports a HOOK: override onAdvance(phase, registered) to control
* when termination occurs and run per-phase actions.
* <p>
*
* When to pick Phaser over CyclicBarrier
* --------------------------------------
* - Party count CHANGES across phases.
* - You want a hook that decides when to terminate (e.g. when all
* parties have deregistered, or after K phases).
* - You want non-blocking arrivals (arrive() returns immediately).
* <p>
*
* Termination
* -----------
* A Phaser terminates when onAdvance returns true. By default it
* terminates when all parties deregister. Once terminated, every
* arrive/await returns immediately (no more synchronisation).
*/
public class PhaserDemo {
public static void main(String[] args) throws InterruptedException {
section("1) Fixed parties, multiple phases");
int N = 3;
Phaser phaser = new Phaser(N) {
@Override protected boolean onAdvance(int phase, int registered) {
System.out.println(" >>> end of phase " + phase + ", still " + registered + " parties <<<");
return registered == 0; // terminate when all deregister (default)
}
};
Thread[] ts = new Thread[N];
for (int i = 0; i < N; i++) {
final int id = i;
ts[i] = new Thread(() -> {
for (int p = 0; p < 3; p++) {
System.out.println(" party " + id + " in phase " + phaser.getPhase());
sleep(30 + 10 * id);
phaser.arriveAndAwaitAdvance();
}
phaser.arriveAndDeregister();
}, "p-" + id);
}
for (Thread t : ts) t.start();
for (Thread t : ts) t.join();
System.out.println("phaser terminated? " + phaser.isTerminated());
section("2) Parties JOINING and LEAVING during execution");
Phaser dynamic = new Phaser(1); // main is party #1
// Start with 2 workers
startWorker(dynamic, "early-A");
startWorker(dynamic, "early-B");
Thread.sleep(20);
// Add a third mid-flight
startWorker(dynamic, "late-C");
// main waits for them
dynamic.arriveAndDeregister(); // main says it's done
while (!dynamic.isTerminated()) sleep(20);
System.out.println("dynamic phaser terminated");
section("3) arrive() — fire-and-forget arrival");
Phaser p = new Phaser(2);
Thread fast = new Thread(() -> { System.out.println(" fast arrives"); p.arrive(); }, "fast");
Thread slow = new Thread(() -> {
sleep(30);
System.out.println(" slow arrives + waits");
p.arriveAndAwaitAdvance();
}, "slow");
fast.start(); slow.start();
fast.join(); slow.join();
System.out.println("phase advanced to " + p.getPhase());
section("done");
}
private static void startWorker(Phaser phaser, String name) {
phaser.register();
new Thread(() -> {
for (int p = 0; p < 2; p++) {
System.out.println(" " + name + " in phase " + phaser.getPhase());
sleep(20);
phaser.arriveAndAwaitAdvance();
}
phaser.arriveAndDeregister();
}, name).start();
}
private static void sleep(long ms) {
try { Thread.sleep(ms); } catch (InterruptedException ignored) { Thread.currentThread().interrupt(); }
}
private static void section(String title) {
System.out.println();
System.out.println("=== " + title + " ===");
}
}