KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > util > concurrent > locks > LockSupport


1 /*
2  * @(#)LockSupport.java 1.6 04/01/24
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.util.concurrent.locks;
9 import java.util.concurrent.*;
10 import sun.misc.Unsafe;
11
12
13 /**
14  * Basic thread blocking primitives for creating locks and other
15  * synchronization classes.
16  *
17  * <p>This class associates with each thread that uses it, a permit
18  * (in the sense of the {@link java.util.concurrent.Semaphore
19  * Semaphore} class). A call to <tt>park</tt> will return immediately
20  * if the permit is available, consuming it in the process; otherwise
21  * it <em>may</em> block. A call to <tt>unpark</tt> makes the permit
22  * available, if it was not already available. (Unlike with Semaphores
23  * though, permits do not accumulate. There is at most one.)
24  *
25  * <p>Methods <tt>park</tt> and <tt>unpark</tt> provide efficient
26  * means of blocking and unblocking threads that do not encounter the
27  * problems that cause the deprecated methods <tt>Thread.suspend</tt>
28  * and <tt>Thread.resume</tt> to be unusable for such purposes: Races
29  * between one thread invoking <tt>park</tt> and another thread trying
30  * to <tt>unpark</tt> it will preserve liveness, due to the
31  * permit. Additionally, <tt>park</tt> will return if the caller's
32  * thread was interrupted, and timeout versions are supported. The
33  * <tt>park</tt> 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 <tt>park</tt> serves as an
36  * optimization of a "busy wait" that does not waste as much time
37  * spinning, but must be paired with an <tt>unpark</tt> to be
38  * effective.
39  *
40  * <p>These methods are designed to be used as tools for creating
41  * higher-level synchronization utilities, and are not in themselves
42  * useful for most concurrency control applications.
43  *
44  * <p><b>Sample Usage.</b> Here is a sketch of a First-in-first-out
45  * non-reentrant lock class.
46  * <pre>
47  * class FIFOMutex {
48  * private AtomicBoolean locked = new AtomicBoolean(false);
49  * private Queue&lt;Thread&gt; waiters = new ConcurrentLinkedQueue&lt;Thread&gt;();
50  *
51  * public void lock() {
52  * boolean wasInterrupted = false;
53  * Thread current = Thread.currentThread();
54  * waiters.add(current);
55  *
56  * // Block while not first in queue or cannot acquire lock
57  * while (waiters.peek() != current ||
58  * !locked.compareAndSet(false, true)) {
59  * LockSupport.park();
60  * if (Thread.interrupted()) // ignore interrupts while waiting
61  * wasInterrupted = true;
62  * }
63  *
64  * waiters.remove();
65  * if (wasInterrupted) // reassert interrupt status on exit
66  * current.interrupt();
67  * }
68  *
69  * public void unlock() {
70  * locked.set(false);
71  * LockSupport.unpark(waiters.peek());
72  * }
73  * }
74  * </pre>
75  */

76
77 public class LockSupport {
78     private LockSupport() {} // Cannot be instantiated.
79

80     // Hotspot implementation via intrinsics API
81
private static final Unsafe unsafe = Unsafe.getUnsafe();
82
83     /**
84      * Make available the permit for the given thread, if it
85      * was not already available. If the thread was blocked on
86      * <tt>park</tt> then it will unblock. Otherwise, its next call
87      * to <tt>park</tt> is guaranteed not to block. This operation
88      * is not guaranteed to have any effect at all if the given
89      * thread has not been started.
90      * @param thread the thread to unpark, or <tt>null</tt>, in which case
91      * this operation has no effect.
92      */

93     public static void unpark(Thread JavaDoc thread) {
94         if (thread != null)
95             unsafe.unpark(thread);
96     }
97
98     /**
99      * Disables the current thread for thread scheduling purposes unless the
100      * permit is available.
101      * <p>If the permit is available then it is consumed and the call returns
102      * immediately; otherwise
103      * the current thread becomes disabled for thread scheduling
104      * purposes and lies dormant until one of three things happens:
105      * <ul>
106      * <li>Some other thread invokes <tt>unpark</tt> with the current thread
107      * as the target; or
108      * <li>Some other thread {@link Thread#interrupt interrupts} the current
109      * thread; or
110      * <li>The call spuriously (that is, for no reason) returns.
111      * </ul>
112      * <p>This method does <em>not</em> report which of these caused the
113      * method to return. Callers should re-check the conditions which caused
114      * the thread to park in the first place. Callers may also determine,
115      * for example, the interrupt status of the thread upon return.
116      */

117     public static void park() {
118         unsafe.park(false, 0L);
119     }
120
121     /**
122      * Disables the current thread for thread scheduling purposes, for up to
123      * the specified waiting time, unless the permit is available.
124      * <p>If the permit is available then it is consumed and the call returns
125      * immediately; otherwise
126      * the current thread becomes disabled for thread scheduling
127      * purposes and lies dormant until one of four things happens:
128      * <ul>
129      * <li>Some other thread invokes <tt>unpark</tt> with the current thread
130      * as the target; or
131      * <li>Some other thread {@link Thread#interrupt interrupts} the current
132      * thread; or
133      * <li>The specified waiting time elapses; or
134      * <li>The call spuriously (that is, for no reason) returns.
135      * </ul>
136      * <p>This method does <em>not</em> report which of these caused the
137      * method to return. Callers should re-check the conditions which caused
138      * the thread to park in the first place. Callers may also determine,
139      * for example, the interrupt status of the thread, or the elapsed time
140      * upon return.
141      *
142      * @param nanos the maximum number of nanoseconds to wait
143      */

144     public static void parkNanos(long nanos) {
145         if (nanos > 0)
146             unsafe.park(false, nanos);
147     }
148
149     /**
150      * Disables the current thread for thread scheduling purposes, until
151      * the specified deadline, unless the permit is available.
152      * <p>If the permit is available then it is consumed and the call returns
153      * immediately; otherwise
154      * the current thread becomes disabled for thread scheduling
155      * purposes and lies dormant until one of four things happens:
156      * <ul>
157      * <li>Some other thread invokes <tt>unpark</tt> with the current thread
158      * as the target; or
159      * <li>Some other thread {@link Thread#interrupt interrupts} the current
160      * thread; or
161      * <li>The specified deadline passes; or
162      * <li>The call spuriously (that is, for no reason) returns.
163      * </ul>
164      * <p>This method does <em>not</em> report which of these caused the
165      * method to return. Callers should re-check the conditions which caused
166      * the thread to park in the first place. Callers may also determine,
167      * for example, the interrupt status of the thread, or the current time
168      * upon return.
169      *
170      * @param deadline the absolute time, in milliseconds from the Epoch, to
171      * wait until
172      */

173     public static void parkUntil(long deadline) {
174         unsafe.park(true, deadline);
175     }
176
177 }
178
179
180
Popular Tags