< prev index next >

src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java

Print this page

 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 }
< prev index next >