1 /*
2  * Written by Doug Lea with assistance from members of JCP JSR-166
3  * Expert Group and released to the public domain, as explained at
4  * http://creativecommons.org/publicdomain/zero/1.0/
5  */
6 
7 package java.util.concurrent.locks;
8 
9 /**
10  * Basic thread blocking primitives for creating locks and other
11  * synchronization classes.
12  *
13  * <p>This class associates, with each thread that uses it, a permit
14  * (in the sense of the {@link java.util.concurrent.Semaphore
15  * Semaphore} class). A call to {@code park} will return immediately
16  * if the permit is available, consuming it in the process; otherwise
17  * it <em>may</em> block.  A call to {@code unpark} makes the permit
18  * available, if it was not already available. (Unlike with Semaphores
19  * though, permits do not accumulate. There is at most one.)
20  * Reliable usage requires the use of volatile (or atomic) variables
21  * to control when to park or unpark.  Orderings of calls to these
22  * methods are maintained with respect to volatile variable accesses,
23  * but not necessarily non-volatile variable accesses.
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(Thread)}.)
45  * The use of these forms rather than the original forms without this
46  * parameter is strongly encouraged. The normal argument to supply as
47  * a {@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  *
54  * <pre> {@code
55  * while (!canProceed()) {
56  *   // ensure request to unpark is visible to other threads
57  *   ...
58  *   LockSupport.park(this);
59  * }}</pre>
60  *
61  * where no actions by the thread publishing a request to unpark,
62  * prior to the call to {@code park}, entail locking or blocking.
63  * Because only one permit is associated with each thread, any
64  * intermediary uses of {@code park}, including implicitly via class
65  * loading, could lead to an unresponsive thread (a "lost unpark").
66  *
67  * <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out
68  * non-reentrant lock class:
69  * <pre> {@code
70  * class FIFOMutex {
71  *   private final AtomicBoolean locked = new AtomicBoolean(false);
72  *   private final Queue<Thread> waiters
73  *     = new ConcurrentLinkedQueue<>();
74  *
75  *   public void lock() {
76  *     boolean wasInterrupted = false;
77  *     // publish current thread for unparkers
78  *     waiters.add(Thread.currentThread());
79  *
80  *     // Block while not first in queue or cannot acquire lock
81  *     while (waiters.peek() != Thread.currentThread() ||
82  *            !locked.compareAndSet(false, true)) {
83  *       LockSupport.park(this);
84  *       // ignore interrupts while waiting
85  *       if (Thread.interrupted())
86  *         wasInterrupted = true;
87  *     }
88  *
89  *     waiters.remove();
90  *     // ensure correct interrupt status on return
91  *     if (wasInterrupted)
92  *       Thread.currentThread().interrupt();
93  *   }
94  *
95  *   public void unlock() {
96  *     locked.set(false);
97  *     LockSupport.unpark(waiters.peek());
98  *   }
99  *
100  *   static {
101  *     // Reduce the risk of "lost unpark" due to classloading
102  *     Class<?> ensureLoaded = LockSupport.class;
103  *   }
104  * }}</pre>
105  */
106 public class LockSupport {
LockSupport()107     private LockSupport() {} // Cannot be instantiated.
108 
setBlocker(Thread t, Object arg)109     private static void setBlocker(Thread t, Object arg) {
110         // Even though volatile, hotspot doesn't need a write barrier here.
111         U.putObject(t, PARKBLOCKER, arg);
112     }
113 
114     /**
115      * Makes available the permit for the given thread, if it
116      * was not already available.  If the thread was blocked on
117      * {@code park} then it will unblock.  Otherwise, its next call
118      * to {@code park} is guaranteed not to block. This operation
119      * is not guaranteed to have any effect at all if the given
120      * thread has not been started.
121      *
122      * @param thread the thread to unpark, or {@code null}, in which case
123      *        this operation has no effect
124      */
unpark(Thread thread)125     public static void unpark(Thread thread) {
126         if (thread != null)
127             U.unpark(thread);
128     }
129 
130     /**
131      * Disables the current thread for thread scheduling purposes unless the
132      * permit is available.
133      *
134      * <p>If the permit is available then it is consumed and the call returns
135      * immediately; otherwise
136      * the current thread becomes disabled for thread scheduling
137      * purposes and lies dormant until one of three things happens:
138      *
139      * <ul>
140      * <li>Some other thread invokes {@link #unpark unpark} with the
141      * current thread as the target; or
142      *
143      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
144      * the current thread; or
145      *
146      * <li>The call spuriously (that is, for no reason) returns.
147      * </ul>
148      *
149      * <p>This method does <em>not</em> report which of these caused the
150      * method to return. Callers should re-check the conditions which caused
151      * the thread to park in the first place. Callers may also determine,
152      * for example, the interrupt status of the thread upon return.
153      *
154      * @param blocker the synchronization object responsible for this
155      *        thread parking
156      * @since 1.6
157      */
park(Object blocker)158     public static void park(Object blocker) {
159         Thread t = Thread.currentThread();
160         setBlocker(t, blocker);
161         U.park(false, 0L);
162         setBlocker(t, null);
163     }
164 
165     /**
166      * Disables the current thread for thread scheduling purposes, for up to
167      * the specified waiting time, unless the permit is available.
168      *
169      * <p>If the permit is available then it is consumed and the call
170      * returns immediately; otherwise the current thread becomes disabled
171      * for thread scheduling purposes and lies dormant until one of four
172      * things happens:
173      *
174      * <ul>
175      * <li>Some other thread invokes {@link #unpark unpark} with the
176      * current thread as the target; or
177      *
178      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
179      * the current thread; or
180      *
181      * <li>The specified waiting time elapses; or
182      *
183      * <li>The call spuriously (that is, for no reason) returns.
184      * </ul>
185      *
186      * <p>This method does <em>not</em> report which of these caused the
187      * method to return. Callers should re-check the conditions which caused
188      * the thread to park in the first place. Callers may also determine,
189      * for example, the interrupt status of the thread, or the elapsed time
190      * upon return.
191      *
192      * @param blocker the synchronization object responsible for this
193      *        thread parking
194      * @param nanos the maximum number of nanoseconds to wait
195      * @since 1.6
196      */
parkNanos(Object blocker, long nanos)197     public static void parkNanos(Object blocker, long nanos) {
198         if (nanos > 0) {
199             Thread t = Thread.currentThread();
200             setBlocker(t, blocker);
201             U.park(false, nanos);
202             setBlocker(t, null);
203         }
204     }
205 
206     /**
207      * Disables the current thread for thread scheduling purposes, until
208      * the specified deadline, unless the permit is available.
209      *
210      * <p>If the permit is available then it is consumed and the call
211      * returns immediately; otherwise the current thread becomes disabled
212      * for thread scheduling purposes and lies dormant until one of four
213      * things happens:
214      *
215      * <ul>
216      * <li>Some other thread invokes {@link #unpark unpark} with the
217      * current thread as the target; or
218      *
219      * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
220      * current thread; or
221      *
222      * <li>The specified deadline passes; or
223      *
224      * <li>The call spuriously (that is, for no reason) returns.
225      * </ul>
226      *
227      * <p>This method does <em>not</em> report which of these caused the
228      * method to return. Callers should re-check the conditions which caused
229      * the thread to park in the first place. Callers may also determine,
230      * for example, the interrupt status of the thread, or the current time
231      * upon return.
232      *
233      * @param blocker the synchronization object responsible for this
234      *        thread parking
235      * @param deadline the absolute time, in milliseconds from the Epoch,
236      *        to wait until
237      * @since 1.6
238      */
parkUntil(Object blocker, long deadline)239     public static void parkUntil(Object blocker, long deadline) {
240         Thread t = Thread.currentThread();
241         setBlocker(t, blocker);
242         U.park(true, deadline);
243         setBlocker(t, null);
244     }
245 
246     /**
247      * Returns the blocker object supplied to the most recent
248      * invocation of a park method that has not yet unblocked, or null
249      * if not blocked.  The value returned is just a momentary
250      * snapshot -- the thread may have since unblocked or blocked on a
251      * different blocker object.
252      *
253      * @param t the thread
254      * @return the blocker
255      * @throws NullPointerException if argument is null
256      * @since 1.6
257      */
getBlocker(Thread t)258     public static Object getBlocker(Thread t) {
259         if (t == null)
260             throw new NullPointerException();
261         return U.getObjectVolatile(t, PARKBLOCKER);
262     }
263 
264     /**
265      * Disables the current thread for thread scheduling purposes unless the
266      * permit is available.
267      *
268      * <p>If the permit is available then it is consumed and the call
269      * returns immediately; otherwise the current thread becomes disabled
270      * for thread scheduling purposes and lies dormant until one of three
271      * things happens:
272      *
273      * <ul>
274      *
275      * <li>Some other thread invokes {@link #unpark unpark} with the
276      * current thread as the target; or
277      *
278      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
279      * the current thread; or
280      *
281      * <li>The call spuriously (that is, for no reason) returns.
282      * </ul>
283      *
284      * <p>This method does <em>not</em> report which of these caused the
285      * method to return. Callers should re-check the conditions which caused
286      * the thread to park in the first place. Callers may also determine,
287      * for example, the interrupt status of the thread upon return.
288      */
park()289     public static void park() {
290         U.park(false, 0L);
291     }
292 
293     /**
294      * Disables the current thread for thread scheduling purposes, for up to
295      * the specified waiting time, unless the permit is available.
296      *
297      * <p>If the permit is available then it is consumed and the call
298      * returns immediately; otherwise the current thread becomes disabled
299      * for thread scheduling purposes and lies dormant until one of four
300      * things happens:
301      *
302      * <ul>
303      * <li>Some other thread invokes {@link #unpark unpark} with the
304      * current thread as the target; or
305      *
306      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
307      * the current thread; or
308      *
309      * <li>The specified waiting time elapses; or
310      *
311      * <li>The call spuriously (that is, for no reason) returns.
312      * </ul>
313      *
314      * <p>This method does <em>not</em> report which of these caused the
315      * method to return. Callers should re-check the conditions which caused
316      * the thread to park in the first place. Callers may also determine,
317      * for example, the interrupt status of the thread, or the elapsed time
318      * upon return.
319      *
320      * @param nanos the maximum number of nanoseconds to wait
321      */
parkNanos(long nanos)322     public static void parkNanos(long nanos) {
323         if (nanos > 0)
324             U.park(false, nanos);
325     }
326 
327     /**
328      * Disables the current thread for thread scheduling purposes, until
329      * the specified deadline, unless the permit is available.
330      *
331      * <p>If the permit is available then it is consumed and the call
332      * returns immediately; otherwise the current thread becomes disabled
333      * for thread scheduling purposes and lies dormant until one of four
334      * things happens:
335      *
336      * <ul>
337      * <li>Some other thread invokes {@link #unpark unpark} with the
338      * current thread as the target; or
339      *
340      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
341      * the current thread; or
342      *
343      * <li>The specified deadline passes; or
344      *
345      * <li>The call spuriously (that is, for no reason) returns.
346      * </ul>
347      *
348      * <p>This method does <em>not</em> report which of these caused the
349      * method to return. Callers should re-check the conditions which caused
350      * the thread to park in the first place. Callers may also determine,
351      * for example, the interrupt status of the thread, or the current time
352      * upon return.
353      *
354      * @param deadline the absolute time, in milliseconds from the Epoch,
355      *        to wait until
356      */
parkUntil(long deadline)357     public static void parkUntil(long deadline) {
358         U.park(true, deadline);
359     }
360 
361     /**
362      * Returns the pseudo-randomly initialized or updated secondary seed.
363      * Copied from ThreadLocalRandom due to package access restrictions.
364      */
nextSecondarySeed()365     static final int nextSecondarySeed() {
366         int r;
367         Thread t = Thread.currentThread();
368         if ((r = U.getInt(t, SECONDARY)) != 0) {
369             r ^= r << 13;   // xorshift
370             r ^= r >>> 17;
371             r ^= r << 5;
372         }
373         else if ((r = java.util.concurrent.ThreadLocalRandom.current().nextInt()) == 0)
374             r = 1; // avoid zero
375         U.putInt(t, SECONDARY, r);
376         return r;
377     }
378 
379     // Hotspot implementation via intrinsics API
380     private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
381     private static final long PARKBLOCKER;
382     private static final long SECONDARY;
383     static {
384         try {
385             PARKBLOCKER = U.objectFieldOffset
386                 (Thread.class.getDeclaredField("parkBlocker"));
387             SECONDARY = U.objectFieldOffset
388                 (Thread.class.getDeclaredField("threadLocalRandomSecondarySeed"));
389         } catch (ReflectiveOperationException e) {
390             throw new Error(e);
391         }
392     }
393 
394 }
395