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