18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 /*
26 * This file is available under and governed by the GNU General Public
27 * License version 2 only, as published by the Free Software Foundation.
28 * However, the following notice accompanied the original version of this
29 * file:
30 *
31 * Written by Doug Lea with assistance from members of JCP JSR-166
32 * Expert Group and released to the public domain, as explained at
33 * http://creativecommons.org/publicdomain/zero/1.0/
34 */
35
36 package java.util.concurrent.locks;
37
38 import jdk.internal.misc.VirtualThreads;
39 import jdk.internal.misc.Unsafe;
40
41 /**
42 * Basic thread blocking primitives for creating locks and other
43 * synchronization classes.
44 *
45 * <p>This class associates, with each thread that uses it, a permit
46 * (in the sense of the {@link java.util.concurrent.Semaphore
47 * Semaphore} class). A call to {@code park} will return immediately
48 * if the permit is available, consuming it in the process; otherwise
49 * it <em>may</em> block. A call to {@code unpark} makes the permit
50 * available, if it was not already available. (Unlike with Semaphores
51 * though, permits do not accumulate. There is at most one.)
52 * Reliable usage requires the use of volatile (or atomic) variables
53 * to control when to park or unpark. Orderings of calls to these
54 * methods are maintained with respect to volatile variable accesses,
55 * but not necessarily non-volatile variable accesses.
56 *
57 * <p>Methods {@code park} and {@code unpark} provide efficient
58 * means of blocking and unblocking threads that do not encounter the
159 * @since 14
160 */
161 public static void setCurrentBlocker(Object blocker) {
162 U.putReferenceOpaque(Thread.currentThread(), PARKBLOCKER, blocker);
163 }
164
165 /**
166 * Makes available the permit for the given thread, if it
167 * was not already available. If the thread was blocked on
168 * {@code park} then it will unblock. Otherwise, its next call
169 * to {@code park} is guaranteed not to block. This operation
170 * is not guaranteed to have any effect at all if the given
171 * thread has not been started.
172 *
173 * @param thread the thread to unpark, or {@code null}, in which case
174 * this operation has no effect
175 */
176 public static void unpark(Thread thread) {
177 if (thread != null) {
178 if (thread.isVirtual()) {
179 VirtualThreads.unpark(thread);
180 } else {
181 U.unpark(thread);
182 }
183 }
184 }
185
186 /**
187 * Disables the current thread for thread scheduling purposes unless the
188 * permit is available.
189 *
190 * <p>If the permit is available then it is consumed and the call returns
191 * immediately; otherwise
192 * the current thread becomes disabled for thread scheduling
193 * purposes and lies dormant until one of three things happens:
194 *
195 * <ul>
196 * <li>Some other thread invokes {@link #unpark unpark} with the
197 * current thread as the target; or
198 *
199 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
200 * the current thread; or
201 *
202 * <li>The call spuriously (that is, for no reason) returns.
203 * </ul>
204 *
205 * <p>This method does <em>not</em> report which of these caused the
206 * method to return. Callers should re-check the conditions which caused
207 * the thread to park in the first place. Callers may also determine,
208 * for example, the interrupt status of the thread upon return.
209 *
210 * @param blocker the synchronization object responsible for this
211 * thread parking
212 * @since 1.6
213 */
214 public static void park(Object blocker) {
215 Thread t = Thread.currentThread();
216 setBlocker(t, blocker);
217 try {
218 if (t.isVirtual()) {
219 VirtualThreads.park();
220 } else {
221 U.park(false, 0L);
222 }
223 } finally {
224 setBlocker(t, null);
225 }
226 }
227
228 /**
229 * Disables the current thread for thread scheduling purposes, for up to
230 * the specified waiting time, unless the permit is available.
231 *
232 * <p>If the specified waiting time is zero or negative, the
233 * method does nothing. Otherwise, if the permit is available then
234 * it is consumed and the call returns immediately; otherwise the
235 * current thread becomes disabled for thread scheduling purposes
236 * and lies dormant until one of four things happens:
237 *
238 * <ul>
239 * <li>Some other thread invokes {@link #unpark unpark} with the
247 * <li>The call spuriously (that is, for no reason) returns.
248 * </ul>
249 *
250 * <p>This method does <em>not</em> report which of these caused the
251 * method to return. Callers should re-check the conditions which caused
252 * the thread to park in the first place. Callers may also determine,
253 * for example, the interrupt status of the thread, or the elapsed time
254 * upon return.
255 *
256 * @param blocker the synchronization object responsible for this
257 * thread parking
258 * @param nanos the maximum number of nanoseconds to wait
259 * @since 1.6
260 */
261 public static void parkNanos(Object blocker, long nanos) {
262 if (nanos > 0) {
263 Thread t = Thread.currentThread();
264 setBlocker(t, blocker);
265 try {
266 if (t.isVirtual()) {
267 VirtualThreads.park(nanos);
268 } else {
269 U.park(false, nanos);
270 }
271 } finally {
272 setBlocker(t, null);
273 }
274 }
275 }
276
277 /**
278 * Disables the current thread for thread scheduling purposes, until
279 * the specified deadline, unless the permit is available.
280 *
281 * <p>If the permit is available then it is consumed and the call
282 * returns immediately; otherwise the current thread becomes disabled
283 * for thread scheduling purposes and lies dormant until one of four
284 * things happens:
285 *
286 * <ul>
287 * <li>Some other thread invokes {@link #unpark unpark} with the
294 *
295 * <li>The call spuriously (that is, for no reason) returns.
296 * </ul>
297 *
298 * <p>This method does <em>not</em> report which of these caused the
299 * method to return. Callers should re-check the conditions which caused
300 * the thread to park in the first place. Callers may also determine,
301 * for example, the interrupt status of the thread, or the current time
302 * upon return.
303 *
304 * @param blocker the synchronization object responsible for this
305 * thread parking
306 * @param deadline the absolute time, in milliseconds from the Epoch,
307 * to wait until
308 * @since 1.6
309 */
310 public static void parkUntil(Object blocker, long deadline) {
311 Thread t = Thread.currentThread();
312 setBlocker(t, blocker);
313 try {
314 if (t.isVirtual()) {
315 VirtualThreads.parkUntil(deadline);
316 } else {
317 U.park(true, deadline);
318 }
319 } finally {
320 setBlocker(t, null);
321 }
322 }
323
324 /**
325 * Returns the blocker object supplied to the most recent
326 * invocation of a park method that has not yet unblocked, or null
327 * if not blocked. The value returned is just a momentary
328 * snapshot -- the thread may have since unblocked or blocked on a
329 * different blocker object.
330 *
331 * @param t the thread
332 * @return the blocker
333 * @throws NullPointerException if argument is null
334 * @since 1.6
335 */
336 public static Object getBlocker(Thread t) {
337 if (t == null)
338 throw new NullPointerException();
349 * things happens:
350 *
351 * <ul>
352 *
353 * <li>Some other thread invokes {@link #unpark unpark} with the
354 * current thread as the target; or
355 *
356 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
357 * the current thread; or
358 *
359 * <li>The call spuriously (that is, for no reason) returns.
360 * </ul>
361 *
362 * <p>This method does <em>not</em> report which of these caused the
363 * method to return. Callers should re-check the conditions which caused
364 * the thread to park in the first place. Callers may also determine,
365 * for example, the interrupt status of the thread upon return.
366 */
367 public static void park() {
368 if (Thread.currentThread().isVirtual()) {
369 VirtualThreads.park();
370 } else {
371 U.park(false, 0L);
372 }
373 }
374
375 /**
376 * Disables the current thread for thread scheduling purposes, for up to
377 * the specified waiting time, unless the permit is available.
378 *
379 * <p>If the specified waiting time is zero or negative, the
380 * method does nothing. Otherwise, if the permit is available then
381 * it is consumed and the call returns immediately; otherwise the
382 * current thread becomes disabled for thread scheduling purposes
383 * and lies dormant until one of four things happens:
384 *
385 * <ul>
386 * <li>Some other thread invokes {@link #unpark unpark} with the
387 * current thread as the target; or
388 *
389 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
390 * the current thread; or
391 *
392 * <li>The specified waiting time elapses; or
393 *
394 * <li>The call spuriously (that is, for no reason) returns.
395 * </ul>
396 *
397 * <p>This method does <em>not</em> report which of these caused the
398 * method to return. Callers should re-check the conditions which caused
399 * the thread to park in the first place. Callers may also determine,
400 * for example, the interrupt status of the thread, or the elapsed time
401 * upon return.
402 *
403 * @param nanos the maximum number of nanoseconds to wait
404 */
405 public static void parkNanos(long nanos) {
406 if (nanos > 0) {
407 if (Thread.currentThread().isVirtual()) {
408 VirtualThreads.park(nanos);
409 } else {
410 U.park(false, nanos);
411 }
412 }
413 }
414
415 /**
416 * Disables the current thread for thread scheduling purposes, until
417 * the specified deadline, unless the permit is available.
418 *
419 * <p>If the permit is available then it is consumed and the call
420 * returns immediately; otherwise the current thread becomes disabled
421 * for thread scheduling purposes and lies dormant until one of four
422 * things happens:
423 *
424 * <ul>
425 * <li>Some other thread invokes {@link #unpark unpark} with the
426 * current thread as the target; or
427 *
428 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
429 * the current thread; or
430 *
431 * <li>The specified deadline passes; or
432 *
433 * <li>The call spuriously (that is, for no reason) returns.
434 * </ul>
435 *
436 * <p>This method does <em>not</em> report which of these caused the
437 * method to return. Callers should re-check the conditions which caused
438 * the thread to park in the first place. Callers may also determine,
439 * for example, the interrupt status of the thread, or the current time
440 * upon return.
441 *
442 * @param deadline the absolute time, in milliseconds from the Epoch,
443 * to wait until
444 */
445 public static void parkUntil(long deadline) {
446 if (Thread.currentThread().isVirtual()) {
447 VirtualThreads.parkUntil(deadline);
448 } else {
449 U.park(true, deadline);
450 }
451 }
452
453 /**
454 * Returns the thread id for the given thread.
455 */
456 static final long getThreadId(Thread thread) {
457 return thread.threadId();
458 }
459
460 // Hotspot implementation via intrinsics API
461 private static final Unsafe U = Unsafe.getUnsafe();
462 private static final long PARKBLOCKER
463 = U.objectFieldOffset(Thread.class, "parkBlocker");
464
465 }
|
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 /*
26 * This file is available under and governed by the GNU General Public
27 * License version 2 only, as published by the Free Software Foundation.
28 * However, the following notice accompanied the original version of this
29 * file:
30 *
31 * Written by Doug Lea with assistance from members of JCP JSR-166
32 * Expert Group and released to the public domain, as explained at
33 * http://creativecommons.org/publicdomain/zero/1.0/
34 */
35
36 package java.util.concurrent.locks;
37
38 import java.util.concurrent.TimeUnit;
39 import jdk.internal.access.JavaLangAccess;
40 import jdk.internal.access.SharedSecrets;
41 import jdk.internal.misc.Unsafe;
42
43 /**
44 * Basic thread blocking primitives for creating locks and other
45 * synchronization classes.
46 *
47 * <p>This class associates, with each thread that uses it, a permit
48 * (in the sense of the {@link java.util.concurrent.Semaphore
49 * Semaphore} class). A call to {@code park} will return immediately
50 * if the permit is available, consuming it in the process; otherwise
51 * it <em>may</em> block. A call to {@code unpark} makes the permit
52 * available, if it was not already available. (Unlike with Semaphores
53 * though, permits do not accumulate. There is at most one.)
54 * Reliable usage requires the use of volatile (or atomic) variables
55 * to control when to park or unpark. Orderings of calls to these
56 * methods are maintained with respect to volatile variable accesses,
57 * but not necessarily non-volatile variable accesses.
58 *
59 * <p>Methods {@code park} and {@code unpark} provide efficient
60 * means of blocking and unblocking threads that do not encounter the
161 * @since 14
162 */
163 public static void setCurrentBlocker(Object blocker) {
164 U.putReferenceOpaque(Thread.currentThread(), PARKBLOCKER, blocker);
165 }
166
167 /**
168 * Makes available the permit for the given thread, if it
169 * was not already available. If the thread was blocked on
170 * {@code park} then it will unblock. Otherwise, its next call
171 * to {@code park} is guaranteed not to block. This operation
172 * is not guaranteed to have any effect at all if the given
173 * thread has not been started.
174 *
175 * @param thread the thread to unpark, or {@code null}, in which case
176 * this operation has no effect
177 */
178 public static void unpark(Thread thread) {
179 if (thread != null) {
180 if (thread.isVirtual()) {
181 JLA.unparkVirtualThread(thread);
182 } else {
183 U.unpark(thread);
184 }
185 }
186 }
187
188 /**
189 * Disables the current thread for thread scheduling purposes unless the
190 * permit is available.
191 *
192 * <p>If the permit is available then it is consumed and the call returns
193 * immediately; otherwise
194 * the current thread becomes disabled for thread scheduling
195 * purposes and lies dormant until one of three things happens:
196 *
197 * <ul>
198 * <li>Some other thread invokes {@link #unpark unpark} with the
199 * current thread as the target; or
200 *
201 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
202 * the current thread; or
203 *
204 * <li>The call spuriously (that is, for no reason) returns.
205 * </ul>
206 *
207 * <p>This method does <em>not</em> report which of these caused the
208 * method to return. Callers should re-check the conditions which caused
209 * the thread to park in the first place. Callers may also determine,
210 * for example, the interrupt status of the thread upon return.
211 *
212 * @param blocker the synchronization object responsible for this
213 * thread parking
214 * @since 1.6
215 */
216 public static void park(Object blocker) {
217 Thread t = Thread.currentThread();
218 setBlocker(t, blocker);
219 try {
220 if (t.isVirtual()) {
221 JLA.parkVirtualThread();
222 } else {
223 U.park(false, 0L);
224 }
225 } finally {
226 setBlocker(t, null);
227 }
228 }
229
230 /**
231 * Disables the current thread for thread scheduling purposes, for up to
232 * the specified waiting time, unless the permit is available.
233 *
234 * <p>If the specified waiting time is zero or negative, the
235 * method does nothing. Otherwise, if the permit is available then
236 * it is consumed and the call returns immediately; otherwise the
237 * current thread becomes disabled for thread scheduling purposes
238 * and lies dormant until one of four things happens:
239 *
240 * <ul>
241 * <li>Some other thread invokes {@link #unpark unpark} with the
249 * <li>The call spuriously (that is, for no reason) returns.
250 * </ul>
251 *
252 * <p>This method does <em>not</em> report which of these caused the
253 * method to return. Callers should re-check the conditions which caused
254 * the thread to park in the first place. Callers may also determine,
255 * for example, the interrupt status of the thread, or the elapsed time
256 * upon return.
257 *
258 * @param blocker the synchronization object responsible for this
259 * thread parking
260 * @param nanos the maximum number of nanoseconds to wait
261 * @since 1.6
262 */
263 public static void parkNanos(Object blocker, long nanos) {
264 if (nanos > 0) {
265 Thread t = Thread.currentThread();
266 setBlocker(t, blocker);
267 try {
268 if (t.isVirtual()) {
269 JLA.parkVirtualThread(nanos);
270 } else {
271 U.park(false, nanos);
272 }
273 } finally {
274 setBlocker(t, null);
275 }
276 }
277 }
278
279 /**
280 * Disables the current thread for thread scheduling purposes, until
281 * the specified deadline, unless the permit is available.
282 *
283 * <p>If the permit is available then it is consumed and the call
284 * returns immediately; otherwise the current thread becomes disabled
285 * for thread scheduling purposes and lies dormant until one of four
286 * things happens:
287 *
288 * <ul>
289 * <li>Some other thread invokes {@link #unpark unpark} with the
296 *
297 * <li>The call spuriously (that is, for no reason) returns.
298 * </ul>
299 *
300 * <p>This method does <em>not</em> report which of these caused the
301 * method to return. Callers should re-check the conditions which caused
302 * the thread to park in the first place. Callers may also determine,
303 * for example, the interrupt status of the thread, or the current time
304 * upon return.
305 *
306 * @param blocker the synchronization object responsible for this
307 * thread parking
308 * @param deadline the absolute time, in milliseconds from the Epoch,
309 * to wait until
310 * @since 1.6
311 */
312 public static void parkUntil(Object blocker, long deadline) {
313 Thread t = Thread.currentThread();
314 setBlocker(t, blocker);
315 try {
316 parkUntil(deadline);
317 } finally {
318 setBlocker(t, null);
319 }
320 }
321
322 /**
323 * Returns the blocker object supplied to the most recent
324 * invocation of a park method that has not yet unblocked, or null
325 * if not blocked. The value returned is just a momentary
326 * snapshot -- the thread may have since unblocked or blocked on a
327 * different blocker object.
328 *
329 * @param t the thread
330 * @return the blocker
331 * @throws NullPointerException if argument is null
332 * @since 1.6
333 */
334 public static Object getBlocker(Thread t) {
335 if (t == null)
336 throw new NullPointerException();
347 * things happens:
348 *
349 * <ul>
350 *
351 * <li>Some other thread invokes {@link #unpark unpark} with the
352 * current thread as the target; or
353 *
354 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
355 * the current thread; or
356 *
357 * <li>The call spuriously (that is, for no reason) returns.
358 * </ul>
359 *
360 * <p>This method does <em>not</em> report which of these caused the
361 * method to return. Callers should re-check the conditions which caused
362 * the thread to park in the first place. Callers may also determine,
363 * for example, the interrupt status of the thread upon return.
364 */
365 public static void park() {
366 if (Thread.currentThread().isVirtual()) {
367 JLA.parkVirtualThread();
368 } else {
369 U.park(false, 0L);
370 }
371 }
372
373 /**
374 * Disables the current thread for thread scheduling purposes, for up to
375 * the specified waiting time, unless the permit is available.
376 *
377 * <p>If the specified waiting time is zero or negative, the
378 * method does nothing. Otherwise, if the permit is available then
379 * it is consumed and the call returns immediately; otherwise the
380 * current thread becomes disabled for thread scheduling purposes
381 * and lies dormant until one of four things happens:
382 *
383 * <ul>
384 * <li>Some other thread invokes {@link #unpark unpark} with the
385 * current thread as the target; or
386 *
387 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
388 * the current thread; or
389 *
390 * <li>The specified waiting time elapses; or
391 *
392 * <li>The call spuriously (that is, for no reason) returns.
393 * </ul>
394 *
395 * <p>This method does <em>not</em> report which of these caused the
396 * method to return. Callers should re-check the conditions which caused
397 * the thread to park in the first place. Callers may also determine,
398 * for example, the interrupt status of the thread, or the elapsed time
399 * upon return.
400 *
401 * @param nanos the maximum number of nanoseconds to wait
402 */
403 public static void parkNanos(long nanos) {
404 if (nanos > 0) {
405 if (Thread.currentThread().isVirtual()) {
406 JLA.parkVirtualThread(nanos);
407 } else {
408 U.park(false, nanos);
409 }
410 }
411 }
412
413 /**
414 * Disables the current thread for thread scheduling purposes, until
415 * the specified deadline, unless the permit is available.
416 *
417 * <p>If the permit is available then it is consumed and the call
418 * returns immediately; otherwise the current thread becomes disabled
419 * for thread scheduling purposes and lies dormant until one of four
420 * things happens:
421 *
422 * <ul>
423 * <li>Some other thread invokes {@link #unpark unpark} with the
424 * current thread as the target; or
425 *
426 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
427 * the current thread; or
428 *
429 * <li>The specified deadline passes; or
430 *
431 * <li>The call spuriously (that is, for no reason) returns.
432 * </ul>
433 *
434 * <p>This method does <em>not</em> report which of these caused the
435 * method to return. Callers should re-check the conditions which caused
436 * the thread to park in the first place. Callers may also determine,
437 * for example, the interrupt status of the thread, or the current time
438 * upon return.
439 *
440 * @param deadline the absolute time, in milliseconds from the Epoch,
441 * to wait until
442 */
443 public static void parkUntil(long deadline) {
444 if (Thread.currentThread().isVirtual()) {
445 long millis = deadline - System.currentTimeMillis();
446 JLA.parkVirtualThread(TimeUnit.MILLISECONDS.toNanos(millis));
447 } else {
448 U.park(true, deadline);
449 }
450 }
451
452 /**
453 * Returns the thread id for the given thread.
454 */
455 static final long getThreadId(Thread thread) {
456 return thread.threadId();
457 }
458
459 // Hotspot implementation via intrinsics API
460 private static final Unsafe U = Unsafe.getUnsafe();
461 private static final long PARKBLOCKER
462 = U.objectFieldOffset(Thread.class, "parkBlocker");
463
464 private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
465 }
|