| LockSupport.java |
1 /*
2 * %W% %E%
3 *
4 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
5 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6 */
7
8 package java.util.concurrent.locks;
9 import java.util.concurrent.*;
10 import sun.misc.Unsafe;
11
12
13 /**
14 * Basic thread blocking primitives for creating locks and other
15 * synchronization classes.
16 *
17 * <p>This class associates, with each thread that uses it, a permit
18 * (in the sense of the {@link java.util.concurrent.Semaphore
19 * Semaphore} class). A call to {@code park} will return immediately
20 * if the permit is available, consuming it in the process; otherwise
21 * it <em>may</em> block. A call to {@code unpark} makes the permit
22 * available, if it was not already available. (Unlike with Semaphores
23 * though, permits do not accumulate. There is at most one.)
24 *
25 * <p>Methods {@code park} and {@code unpark} provide efficient
26 * means of blocking and unblocking threads that do not encounter the
27 * problems that cause the deprecated methods {@code Thread.suspend}
28 * and {@code Thread.resume} to be unusable for such purposes: Races
29 * between one thread invoking {@code park} and another thread trying
30 * to {@code unpark} it will preserve liveness, due to the
31 * permit. Additionally, {@code park} will return if the caller's
32 * thread was interrupted, and timeout versions are supported. The
33 * {@code park} method may also return at any other time, for "no
34 * reason", so in general must be invoked within a loop that rechecks
35 * conditions upon return. In this sense {@code park} serves as an
36 * optimization of a "busy wait" that does not waste as much time
37 * spinning, but must be paired with an {@code unpark} to be
38 * effective.
39 *
40 * <p>The three forms of {@code park} each also support a
41 * {@code blocker} object parameter. This object is recorded while
42 * the thread is blocked to permit monitoring and diagnostic tools to
43 * identify the reasons that threads are blocked. (Such tools may
44 * access blockers using method {@link #getBlocker}.) The use of these
45 * forms rather than the original forms without this parameter is
46 * strongly encouraged. The normal argument to supply as a
47 * {@code blocker} within a lock implementation is {@code this}.
48 *
49 * <p>These methods are designed to be used as tools for creating
50 * higher-level synchronization utilities, and are not in themselves
51 * useful for most concurrency control applications. The {@code park}
52 * method is designed for use only in constructions of the form:
53 * <pre>while (!canProceed()) { ... LockSupport.park(this); }</pre>
54 * where neither {@code canProceed} nor any other actions prior to the
55 * call to {@code park} entail locking or blocking. Because only one
56 * permit is associated with each thread, any intermediary uses of
57 * {@code park} could interfere with its intended effects.
58 *
59 * <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out
60 * non-reentrant lock class:
61 * <pre>{@code
62 * class FIFOMutex {
63 * private final AtomicBoolean locked = new AtomicBoolean(false);
64 * private final Queue<Thread> waiters
65 * = new ConcurrentLinkedQueue<Thread>();
66 *
67 * public void lock() {
68 * boolean wasInterrupted = false;
69 * Thread current = Thread.currentThread();
70 * waiters.add(current);
71 *
72 * // Block while not first in queue or cannot acquire lock
73 * while (waiters.peek() != current ||
74 * !locked.compareAndSet(false, true)) {
75 * LockSupport.park(this);
76 * if (Thread.interrupted()) // ignore interrupts while waiting
77 * wasInterrupted = true;
78 * }
79 *
80 * waiters.remove();
81 * if (wasInterrupted) // reassert interrupt status on exit
82 * current.interrupt();
83 * }
84 *
85 * public void unlock() {
86 * locked.set(false);
87 * LockSupport.unpark(waiters.peek());
88 * }
89 * }}</pre>
90 */
91
92 public class LockSupport {
93 private LockSupport() {} // Cannot be instantiated.
94
95 // Hotspot implementation via intrinsics API
96 private static final Unsafe unsafe = Unsafe.getUnsafe();
97 private static final long parkBlockerOffset;
98
99 static {
100 try {
101 parkBlockerOffset = unsafe.objectFieldOffset
102 (java.lang.Thread.class.getDeclaredField("parkBlocker"));
103 } catch (Exception ex) { throw new Error(ex); }
104 }
105
106 private static void setBlocker(Thread t, Object arg) {
107 // Even though volatile, hotspot doesn't need a write barrier here.
108 unsafe.putObject(t, parkBlockerOffset, arg);
109 }
110
111 /**
112 * Makes available the permit for the given thread, if it
113 * was not already available. If the thread was blocked on
114 * {@code park} then it will unblock. Otherwise, its next call
115 * to {@code park} is guaranteed not to block. This operation
116 * is not guaranteed to have any effect at all if the given
117 * thread has not been started.
118 *
119 * @param thread the thread to unpark, or {@code null}, in which case
120 * this operation has no effect
121 */
122 public static void unpark(Thread thread) {
123 if (thread != null)
124 unsafe.unpark(thread);
125 }
126
127 /**
128 * Disables the current thread for thread scheduling purposes unless the
129 * permit is available.
130 *
131 * <p>If the permit is available then it is consumed and the call returns
132 * immediately; otherwise
133 * the current thread becomes disabled for thread scheduling
134 * purposes and lies dormant until one of three things happens:
135 *
136 * <ul>
137 * <li>Some other thread invokes {@link #unpark unpark} with the
138 * current thread as the target; or
139 *
140 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
141 * the current thread; or
142 *
143 * <li>The call spuriously (that is, for no reason) returns.
144 * </ul>
145 *
146 * <p>This method does <em>not</em> report which of these caused the
147 * method to return. Callers should re-check the conditions which caused
148 * the thread to park in the first place. Callers may also determine,
149 * for example, the interrupt status of the thread upon return.
150 *
151 * @param blocker the synchronization object responsible for this
152 * thread parking
153 * @since 1.6
154 */
155 public static void park(Object blocker) {
156 Thread t = Thread.currentThread();
157 setBlocker(t, blocker);
158 unsafe.park(false, 0L);
159 setBlocker(t, null);
160 }
161
162 /**
163 * Disables the current thread for thread scheduling purposes, for up to
164 * the specified waiting time, unless the permit is available.
165 *
166 * <p>If the permit is available then it is consumed and the call
167 * returns immediately; otherwise the current thread becomes disabled
168 * for thread scheduling purposes and lies dormant until one of four
169 * things happens:
170 *
171 * <ul>
172 * <li>Some other thread invokes {@link #unpark unpark} with the
173 * current thread as the target; or
174 *
175 * <li>Some other thread {@linkplain Thread#interrupt interrupts} the current
176 * thread; or
177 *
178 * <li>The specified waiting time elapses; or
179 *
180 * <li>The call spuriously (that is, for no reason) returns.
181 * </ul>
182 *
183 * <p>This method does <em>not</em> report which of these caused the
184 * method to return. Callers should re-check the conditions which caused
185 * the thread to park in the first place. Callers may also determine,
186 * for example, the interrupt status of the thread, or the elapsed time
187 * upon return.
188 *
189 * @param blocker the synchronization object responsible for this
190 * thread parking
191 * @param nanos the maximum number of nanoseconds to wait
192 * @since 1.6
193 */
194 public static void parkNanos(Object blocker, long nanos) {
195 if (nanos > 0) {
196 Thread t = Thread.currentThread();
197 setBlocker(t, blocker);
198 unsafe.park(false, nanos);
199 setBlocker(t, null);
200 }
201 }
202
203 /**
204 * Disables the current thread for thread scheduling purposes, until
205 * the specified deadline, unless the permit is available.
206 *
207 * <p>If the permit is available then it is consumed and the call
208 * returns immediately; otherwise the current thread becomes disabled
209 * for thread scheduling purposes and lies dormant until one of four
210 * things happens:
211 *
212 * <ul>
213 * <li>Some other thread invokes {@link #unpark unpark} with the
214 * current thread as the target; or
215 *
216 * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
217 * current thread; or
218 *
219 * <li>The specified deadline passes; or
220 *
221 * <li>The call spuriously (that is, for no reason) returns.
222 * </ul>
223 *
224 * <p>This method does <em>not</em> report which of these caused the
225 * method to return. Callers should re-check the conditions which caused
226 * the thread to park in the first place. Callers may also determine,
227 * for example, the interrupt status of the thread, or the current time
228 * upon return.
229 *
230 * @param blocker the synchronization object responsible for this
231 * thread parking
232 * @param deadline the absolute time, in milliseconds from the Epoch,
233 * to wait until
234 * @since 1.6
235 */
236 public static void parkUntil(Object blocker, long deadline) {
237 Thread t = Thread.currentThread();
238 setBlocker(t, blocker);
239 unsafe.park(true, deadline);
240 setBlocker(t, null);
241 }
242
243 /**
244 * Returns the blocker object supplied to the most recent
245 * invocation of a park method that has not yet unblocked, or null
246 * if not blocked. The value returned is just a momentary
247 * snapshot -- the thread may have since unblocked or blocked on a
248 * different blocker object.
249 *
250 * @return the blocker
251 * @since 1.6
252 */
253 public static Object getBlocker(Thread t) {
254 return unsafe.getObjectVolatile(t, parkBlockerOffset);
255 }
256
257 /**
258 * Disables the current thread for thread scheduling purposes unless the
259 * permit is available.
260 *
261 * <p>If the permit is available then it is consumed and the call
262 * returns immediately; otherwise the current thread becomes disabled
263 * for thread scheduling purposes and lies dormant until one of three
264 * things happens:
265 *
266 * <ul>
267 *
268 * <li>Some other thread invokes {@link #unpark unpark} with the
269 * current thread as the target; or
270 *
271 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
272 * the current thread; or
273 *
274 * <li>The call spuriously (that is, for no reason) returns.
275 * </ul>
276 *
277 * <p>This method does <em>not</em> report which of these caused the
278 * method to return. Callers should re-check the conditions which caused
279 * the thread to park in the first place. Callers may also determine,
280 * for example, the interrupt status of the thread upon return.
281 */
282 public static void park() {
283 unsafe.park(false, 0L);
284 }
285
286 /**
287 * Disables the current thread for thread scheduling purposes, for up to
288 * the specified waiting time, unless the permit is available.
289 *
290 * <p>If the permit is available then it is consumed and the call
291 * returns immediately; otherwise the current thread becomes disabled
292 * for thread scheduling purposes and lies dormant until one of four
293 * things happens:
294 *
295 * <ul>
296 * <li>Some other thread invokes {@link #unpark unpark} with the
297 * current thread as the target; or
298 *
299 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
300 * the current thread; or
301 *
302 * <li>The specified waiting time elapses; or
303 *
304 * <li>The call spuriously (that is, for no reason) returns.
305 * </ul>
306 *
307 * <p>This method does <em>not</em> report which of these caused the
308 * method to return. Callers should re-check the conditions which caused
309 * the thread to park in the first place. Callers may also determine,
310 * for example, the interrupt status of the thread, or the elapsed time
311 * upon return.
312 *
313 * @param nanos the maximum number of nanoseconds to wait
314 */
315 public static void parkNanos(long nanos) {
316 if (nanos > 0)
317 unsafe.park(false, nanos);
318 }
319
320 /**
321 * Disables the current thread for thread scheduling purposes, until
322 * the specified deadline, unless the permit is available.
323 *
324 * <p>If the permit is available then it is consumed and the call
325 * returns immediately; otherwise the current thread becomes disabled
326 * for thread scheduling purposes and lies dormant until one of four
327 * things happens:
328 *
329 * <ul>
330 * <li>Some other thread invokes {@link #unpark unpark} with the
331 * current thread as the target; or
332 *
333 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
334 * the current thread; or
335 *
336 * <li>The specified deadline passes; or
337 *
338 * <li>The call spuriously (that is, for no reason) returns.
339 * </ul>
340 *
341 * <p>This method does <em>not</em> report which of these caused the
342 * method to return. Callers should re-check the conditions which caused
343 * the thread to park in the first place. Callers may also determine,
344 * for example, the interrupt status of the thread, or the current time
345 * upon return.
346 *
347 * @param deadline the absolute time, in milliseconds from the Epoch,
348 * to wait until
349 */
350 public static void parkUntil(long deadline) {
351 unsafe.park(true, deadline);
352 }
353 }
354