-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathThreadLifecycle.java
More file actions
141 lines (127 loc) · 5.1 KB
/
Copy pathThreadLifecycle.java
File metadata and controls
141 lines (127 loc) · 5.1 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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package Phase7_Concurrency.Multithreading;
import java.util.concurrent.locks.LockSupport;
/**
* Thread Lifecycle
* ----------------
* A Thread moves through a small set of states defined by Thread.State:
* <p>
*
* NEW - constructed but start() has NOT been called yet.
* RUNNABLE - eligible to run on a CPU. May be currently
* running, may be ready and waiting for a core.
* BLOCKED - waiting to acquire an INTRINSIC monitor lock
* (entering a synchronized block / method whose
* lock another thread holds).
* WAITING - waiting indefinitely for another thread:
* wait() (no timeout)
* join() (no timeout)
* LockSupport.park()
* TIMED_WAITING - waiting with a timeout:
* sleep(ms)
* wait(ms)
* join(ms)
* LockSupport.parkNanos / parkUntil
* TERMINATED - run() has returned (normally or via uncaught
* exception). Cannot be restarted.
* <p>
*
* Diagram
* -------
* <p>
*
* start() schedule
* NEW ----------> RUNNABLE <--------------> running on CPU
* | ^ (the JVM/OS does this)
* synchronized -->| |
* v |
* BLOCKED (waiting for a monitor)
* <p>
*
* wait/join/park -->|
* v
* WAITING / TIMED_WAITING
* |
* notify/timeout
* v
* RUNNABLE
* <p>
*
* run() returns
* v
* TERMINATED
* <p>
*
* Important Notes
* ---------------
* 1. RUNNABLE includes "ready but waiting for CPU" too. There is NO
* separate READY state in Java's enum.
* 2. BLOCKED only refers to INTRINSIC LOCK contention. Threads waiting
* on a Lock from java.util.concurrent.locks are WAITING /
* TIMED_WAITING, not BLOCKED — because Lock uses LockSupport.park.
* 3. TERMINATED is final. You cannot restart a terminated thread.
* <p>
*
* This file walks through each state and prints what getState() returns.
*/
public class ThreadLifecycle {
private static final Object MONITOR = new Object();
public static void main(String[] args) throws InterruptedException {
section("1) NEW — before start()");
Thread fresh = new Thread(() -> {});
System.out.println("state = " + fresh.getState()); // NEW
section("2) RUNNABLE — after start()");
Thread runnable = new Thread(() -> { while (!Thread.currentThread().isInterrupted()) {} });
runnable.start();
Thread.sleep(50);
System.out.println("state = " + runnable.getState()); // RUNNABLE
runnable.interrupt();
runnable.join();
section("3) TIMED_WAITING — sleeping");
Thread sleeper = new Thread(() -> { try { Thread.sleep(500); } catch (InterruptedException ignored) {} });
sleeper.start();
Thread.sleep(50);
System.out.println("state = " + sleeper.getState()); // TIMED_WAITING
sleeper.join();
section("4) WAITING — wait() / join() / park()");
Thread parked = new Thread(LockSupport::park);
parked.start();
Thread.sleep(50);
System.out.println("state = " + parked.getState()); // WAITING
LockSupport.unpark(parked);
parked.join();
section("5) BLOCKED — waiting on a synchronized monitor");
Thread holder = new Thread(() -> {
synchronized (MONITOR) {
try { Thread.sleep(300); } catch (InterruptedException ignored) {}
}
}, "holder");
Thread waiter = new Thread(() -> {
synchronized (MONITOR) { // will block until holder releases
// do nothing once we get it
}
}, "waiter");
holder.start();
Thread.sleep(50); // let holder grab the monitor
waiter.start();
Thread.sleep(50); // let waiter contend
System.out.println("holder state = " + holder.getState()); // TIMED_WAITING (inside sleep)
System.out.println("waiter state = " + waiter.getState()); // BLOCKED
holder.join();
waiter.join();
section("6) TERMINATED — after run() returns");
Thread done = new Thread(() -> {});
done.start();
done.join();
System.out.println("state = " + done.getState()); // TERMINATED
section("7) Cannot restart a TERMINATED thread");
try { done.start(); }
catch (IllegalThreadStateException e) {
System.out.println("expected: " + e);
}
section("done");
}
private static void section(String title) {
System.out.println();
System.out.println("=== " + title + " ===");
}
}