OSDN Git Service

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