ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/Condition.java
Revision: 1.6
Committed: Tue Jul 8 00:46:33 2003 UTC (20 years, 11 months ago) by dl
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +2 -2 lines
State: FILE REMOVED
Log Message:
Locks in subpackage; fairness params added

File Contents

# User Rev Content
1 dl 1.2 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain. Use, modify, and
4     * redistribute this code in any way without acknowledgement.
5     */
6    
7 tim 1.1 package java.util.concurrent;
8     import java.util.Date;
9    
10     /**
11 dholmes 1.5 * <tt>Condition</tt> factors out the <tt>Object</tt> monitor
12 dl 1.4 * methods ({@link Object#wait() wait}, {@link Object#notify notify}
13     * and {@link Object#notifyAll notifyAll}) into distinct objects to
14     * give the effect of having multiple wait-sets per object
15 dholmes 1.5 * monitor. It also generalises the monitor methods to allow them to
16 tim 1.1 * be used with arbitrary {@link Lock} implementations when needed.
17     *
18 dholmes 1.5 * <p>Conditions (also known as <em>condition queues</em> or
19     * <em>condition variables</em>) provide
20 tim 1.1 * a means for one thread to suspend execution (to &quot;wait&quot;) until
21 brian 1.3 * notified by another thread that some state condition may now be true.
22     * Because access to this shared state information
23     * occurs in different threads, it must be protected, and invariably
24     * a lock of some form is associated with the condition. The key
25 dholmes 1.5 * property that waiting for a condition provides is that it
26 tim 1.1 * <em>atomically</em> releases the associated lock and suspends the current
27 brian 1.3 * thread, just like <tt>Object.wait</tt>.
28 tim 1.1 *
29 brian 1.3 * <p>A <tt>Condition</tt> instance is intrinsically bound to a lock, either
30     * the built-in monitor lock of an object, or a {@link Lock} instance.
31 tim 1.1 * To obtain a <tt>Condition</tt> instance for a particular object's monitor
32     * lock
33     * use the {@link Locks#newConditionFor(Object)} method.
34     * To obtain a <tt>Condition</tt> instance for a particular {@link Lock}
35     * instance use its {@link Lock#newCondition} method.
36     *
37 brian 1.3 * <p>As an example, suppose we have a bounded buffer which supports
38     * <tt>put</tt> and <tt>take</tt> methods. If a
39     * <tt>take</tt> is attempted on an empty buffer, then the thread will block
40 tim 1.1 * until an item becomes available; if a <tt>put</tt> is attempted on a
41     * full buffer, then the thread will block until a space becomes available.
42     * We would like to keep waiting <tt>put</tt> threads and <tt>take</tt>
43     * threads in separate wait-sets so that we can use the optimisation of
44 brian 1.3 * only notifying a single thread at a time when items or spaces become
45 tim 1.1 * available in the buffer. This can be achieved using either two
46     * {@link Condition} instances, or one {@link Condition} instance and the
47     * actual
48     * monitor wait-set. For clarity we'll use two {@link Condition} instances.
49     * <pre><code>
50     * class BoundedBuffer {
51     * <b>final Condition notFull = Locks.newConditionFor(this);
52     * final Condition notEmpty = Locks.newConditionFor(this); </b>
53     *
54     * Object[] items = new Object[100];
55     * int putptr, takeptr, count;
56     *
57     * public <b>synchronized</b> void put(Object x)
58     * throws InterruptedException {
59     * while (count == items.length)
60     * <b>notFull.await();</b>
61     * items[putptr] = x;
62     * if (++putptr == items.length) putptr = 0;
63     * ++count;
64     * <b>notEmpty.signal();</b>
65     * }
66     *
67     * public <b>synchronized</b> Object take() throws InterruptedException {
68     * while (count == 0)
69     * <b>notEmpty.await();</b>
70     * Object x = items[takeptr];
71     * if (++takeptr == items.length) takeptr = 0;
72     * --count;
73     * <b>notFull.signal();</b>
74     * return x;
75     * }
76     * }
77     * </code></pre>
78     *
79     * <p>If we were to use a standalone {@link Lock} object, such as a
80     * {@link ReentrantLock} then we would write the example as so:
81     * <pre><code>
82     * class BoundedBuffer {
83     * <b>Lock lock = new ReentrantLock();</b>
84     * final Condition notFull = <b>lock.newCondition(); </b>
85     * final Condition notEmpty = <b>lock.newCondition(); </b>
86     *
87     * Object[] items = new Object[100];
88     * int putptr, takeptr, count;
89     *
90     * public void put(Object x) throws InterruptedException {
91     * <b>lock.lock();
92     * try {</b>
93     * while (count == items.length)
94     * <b>notFull.await();</b>
95     * items[putptr] = x;
96     * if (++putptr == items.length) putptr = 0;
97     * ++count;
98     * <b>notEmpty.signal();</b>
99     * <b>} finally {
100     * lock.unlock();
101     * }</b>
102     * }
103     *
104     * public Object take() throws InterruptedException {
105     * <b>lock.lock();
106     * try {</b>
107     * while (count == 0)
108     * <b>notEmpty.await();</b>
109     * Object x = items[takeptr];
110     * if (++takeptr == items.length) takeptr = 0;
111     * --count;
112     * <b>notFull.signal();</b>
113     * return x;
114     * <b>} finally {
115     * lock.unlock();
116     * }</b>
117     * }
118     * }
119     * </code></pre>
120     *
121     * <p>A <tt>Condition</tt> implementation can provide behavior and semantics
122     * that is
123     * different from that of the <tt>Object</tt> monitor methods, such as
124     * guaranteed ordering for notifications, or not requiring a lock to be held
125     * when performing notifications.
126     * If an implementation provides such specialised semantics then the
127     * implementation must document those semantics.
128     *
129     * <p>Note that <tt>Condition</tt> instances are just normal objects and can
130     * themselves be used as the target in a <tt>synchronized</tt> statement,
131     * and can have their own monitor {@link Object#wait wait} and
132     * {@link Object#notify notification} methods invoked.
133     * Acquiring the monitor lock of a <tt>Condition</tt> instance, or using its
134 brian 1.3 * monitor methods, has no specified relationship with acquiring the
135 tim 1.1 * {@link Lock} associated with that <tt>Condition</tt> or the use of it's
136     * {@link #await waiting} and {@link #signal signalling} methods.
137     * It is recommended that to avoid confusion you never use <tt>Condition</tt>
138     * instances in this way, except perhaps within their own implementation.
139     *
140     * <p>Except where noted, passing a <tt>null</tt> value for any parameter
141     * will result in a {@link NullPointerException} being thrown.
142     *
143     * <h3>Implementation Considerations</h3>
144     *
145 brian 1.3 * <p>When waiting upon a <tt>Condition</tt>, a &quot;<em>spurious
146 tim 1.1 * wakeup</em>&quot; is permitted to occur, in
147     * general, as a concession to the underlying platform semantics.
148     * This has little practical impact on most application programs as a
149     * <tt>Condition</tt> should always be waited upon in a loop, testing
150 brian 1.3 * the state predicate that is being waited for. An implementation is
151 tim 1.1 * free to remove the possibility of spurious wakeups but it is
152     * recommended that applications programmers always assume that they can
153     * occur and so always wait in a loop.
154     *
155 dl 1.2 * <p>The three forms of condition waiting
156 tim 1.1 * (interruptible, non-interruptible, and timed) may differ in their ease of
157     * implementation on some platforms and in their performance characteristics.
158     * In particular, it may be difficult to provide these features and maintain
159     * specific semantics such as ordering guarantees.
160     * Further, the ability to interrupt the actual suspension of the thread may
161     * not always be feasible to implement on all platforms.
162     * <p>Consequently, an implementation is not required to define exactly the
163     * same guarantees or semantics for all three forms of waiting, nor is it
164     * required to support interruption of the actual suspension of the thread.
165     * <p>An implementation is required to
166     * clearly document the semantics and guarantees provided by each of the
167     * waiting methods, and when an implementation does support interruption of
168     * thread suspension then it must obey the interruption semantics as defined
169     * in this interface.
170 dholmes 1.5 * <p>As interruption generally implies cancellation, and checks for
171     * interruption are often infrequent, an implementation can favor responding
172     * to an interrupt over normal method return. This is true even if it can be
173     * shown that the interrupt occurred after another action may have unblocked
174     * the thread. An implementation should document this behaviour.
175 tim 1.1 *
176     *
177     * @since 1.5
178     * @spec JSR-166
179 dl 1.6 * @revised $Date: 2003/06/26 05:42:58 $
180     * @editor $Author: dholmes $
181 dl 1.4 * @author Doug Lea
182     */
183 tim 1.1 public interface Condition {
184    
185     /**
186     * Causes the current thread to wait until it is signalled or
187     * {@link Thread#interrupt interrupted}.
188     *
189     * <p>The lock associated with this <tt>Condition</tt> is atomically
190     * released and the current thread becomes disabled for thread scheduling
191     * purposes and lies dormant until <em>one</em> of four things happens:
192     * <ul>
193     * <li>Some other thread invokes the {@link #signal} method for this
194     * <tt>Condition</tt> and the current thread happens to be chosen as the
195     * thread to be awakened; or
196     * <li>Some other thread invokes the {@link #signalAll} method for this
197     * <tt>Condition</tt>; or
198     * <li> Some other thread {@link Thread#interrupt interrupts} the current
199     * thread, and interruption of thread suspension is supported; or
200     * <li>A &quot;<em>spurious wakeup</em>&quot; occurs
201     * </ul>
202     *
203     * <p>In all cases, before this method can return the current thread must
204     * re-acquire the lock associated with this condition. When the
205     * thread returns it is <em>guaranteed</em> to hold this lock.
206     *
207     * <p>If the current thread:
208     * <ul>
209     * <li>has its interrupted status set on entry to this method; or
210     * <li>is {@link Thread#interrupt interrupted} while waiting
211     * and interruption of thread suspension is supported,
212     * </ul>
213     * then {@link InterruptedException} is thrown and the current thread's
214     * interrupted status is cleared. It is not specified, in the first
215     * case, whether or not the test for interruption occurs before the lock
216     * is released.
217     *
218     * <p><b>Implementation Considerations</b>
219     * <p>The current thread is assumed to hold the lock associated with this
220     * <tt>Condition</tt> when this method is called.
221     * It is up to the implementation to determine if this is
222     * the case and if not, how to respond. Typically, an exception will be
223     * thrown (such as {@link IllegalMonitorStateException}) and the
224     * implementation must document that fact.
225     *
226 dholmes 1.5 * <p>An implementation can favour responding to an interrupt over normal
227     * method return in response to a signal. In that case the implementation
228     * must ensure that the signal is redirected to another waiting thread, if
229     * there is one.
230     *
231 tim 1.1 * @throws InterruptedException if the current thread is interrupted (and
232     * interruption of thread suspension is supported).
233 dl 1.2 **/
234 dl 1.4 void await() throws InterruptedException;
235 tim 1.1
236     /**
237     * Causes the current thread to wait until it is signalled.
238     *
239     * <p>The lock associated with this condition is atomically
240     * released and the current thread becomes disabled for thread scheduling
241     * purposes and lies dormant until <em>one</em> of three things happens:
242     * <ul>
243     * <li>Some other thread invokes the {@link #signal} method for this
244     * <tt>Condition</tt> and the current thread happens to be chosen as the
245     * thread to be awakened; or
246     * <li>Some other thread invokes the {@link #signalAll} method for this
247     * <tt>Condition</tt>; or
248     * <li>A &quot;<em>spurious wakeup</em>&quot; occurs
249     * </ul>
250     *
251     * <p>In all cases, before this method can return the current thread must
252     * re-acquire the lock associated with this condition. When the
253     * thread returns it is <em>guaranteed</em> to hold this lock.
254     *
255     * <p>If the current thread's interrupt status is set when it enters
256     * this method, or it is {@link Thread#interrupt interrupted}
257     * while waiting, it will continue to wait until signalled. When it finally
258     * returns from this method it's <em>interrupted status</em> will still
259     * be set.
260     *
261     * <p><b>Implementation Considerations</b>
262     * <p>The current thread is assumed to hold the lock associated with this
263     * <tt>Condition</tt> when this method is called.
264     * It is up to the implementation to determine if this is
265     * the case and if not, how to respond. Typically, an exception will be
266     * thrown (such as {@link IllegalMonitorStateException}) and the
267     * implementation must document that fact.
268     *
269 dl 1.2 **/
270 dl 1.4 void awaitUninterruptibly();
271 tim 1.1
272     /**
273 dl 1.2 * Causes the current thread to wait until it is signalled or interrupted,
274 tim 1.1 * or the specified waiting time elapses.
275     *
276     * <p>The lock associated with this condition is atomically
277     * released and the current thread becomes disabled for thread scheduling
278     * purposes and lies dormant until <em>one</em> of five things happens:
279     * <ul>
280     * <li>Some other thread invokes the {@link #signal} method for this
281     * <tt>Condition</tt> and the current thread happens to be chosen as the
282     * thread to be awakened; or
283     * <li>Some other thread invokes the {@link #signalAll} method for this
284     * <tt>Condition</tt>; or
285     * <li> Some other thread {@link Thread#interrupt interrupts} the current
286     * thread, and interruption of thread suspension is supported; or
287     * <li>The specified waiting time elapses; or
288     * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
289     * </ul>
290     *
291     * <p>In all cases, before this method can return the current thread must
292     * re-acquire the lock associated with this condition. When the
293     * thread returns it is <em>guaranteed</em> to hold this lock.
294     *
295     * <p>If the current thread:
296     * <ul>
297     * <li>has its interrupted status set on entry to this method; or
298     * <li>is {@link Thread#interrupt interrupted} while waiting
299     * and interruption of thread suspension is supported,
300     * </ul>
301     * then {@link InterruptedException} is thrown and the current thread's
302     * interrupted status is cleared. It is not specified, in the first
303     * case, whether or not the test for interruption occurs before the lock
304     * is released.
305     *
306 dl 1.2 * <p>The method returns an estimate of the number of nanoseconds
307 tim 1.1 * remaining to wait given the supplied <tt>nanosTimeout</tt>
308 dl 1.2 * value upon return, or a value less than or equal to zero if it
309     * timed out. This value can be used to determine whether and how
310     * long to re-wait in cases where the wait returns but an awaited
311 tim 1.1 * condition still does not hold. Typical uses of this method take
312     * the following form:
313     *
314     * <pre>
315     * synchronized boolean aMethod(long timeout, TimeUnit unit) {
316     * long nanosTimeout = unit.toNanos(timeout);
317     * while (!conditionBeingWaitedFor) {
318     * if (nanosTimeout &gt; 0)
319     * nanosTimeout = theCondition.awaitNanos(nanosTimeout);
320     * else
321     * return false;
322     * }
323     * // ...
324     * }
325     * </pre>
326     *
327     * <p> Design note: This method requires a nanosecond argument so
328     * as to avoid truncation errors in reporting remaining times.
329     * Such precision loss would make it difficult for programmers to
330     * ensure that total waiting times are not systematically shorter
331     * than specified when re-waits occur.
332     *
333     * <p><b>Implementation Considerations</b>
334     * <p>The current thread is assumed to hold the lock associated with this
335     * <tt>Condition</tt> when this method is called.
336     * It is up to the implementation to determine if this is
337     * the case and if not, how to respond. Typically, an exception will be
338     * thrown (such as {@link IllegalMonitorStateException}) and the
339     * implementation must document that fact.
340     *
341 dholmes 1.5 * <p>An implementation can favour responding to an interrupt over normal
342     * method return in response to a signal, or over indicating the elapse
343     * of the specified waiting time. In either case the implementation
344     * must ensure that the signal is redirected to another waiting thread, if
345     * there is one.
346 dl 1.2 *
347 tim 1.1 * @param nanosTimeout the maximum time to wait, in nanoseconds
348 dl 1.2 * @return A value less than or equal to zero if the wait has
349     * timed out; otherwise an estimate, that
350 tim 1.1 * is strictly less than the <tt>nanosTimeout</tt> argument,
351     * of the time still remaining when this method returned.
352     *
353     * @throws InterruptedException if the current thread is interrupted (and
354     * interruption of thread suspension is supported).
355     */
356 dl 1.4 long awaitNanos(long nanosTimeout) throws InterruptedException;
357 tim 1.1
358 dl 1.2 /**
359     * Causes the current thread to wait until it is signalled or interrupted,
360     * or the specified waiting time elapses. This method is behaviorally
361     * equivalent to:<br>
362     * <pre>
363     * awaitNanos(unit.toNanos(time)) &gt; 0
364     * </pre>
365     * @param time the maximum time to wait
366     * @param unit the time unit of the <tt>time</tt> argument.
367     * @return <tt>false</tt> if the waiting time detectably elapsed
368     * before return from the method, else <tt>true</tt>.
369 dl 1.4 * @throws InterruptedException if the current thread is interrupted (and
370     * interruption of thread suspension is supported).
371 dl 1.2 */
372 dl 1.4 boolean await(long time, TimeUnit unit) throws InterruptedException;
373 tim 1.1
374     /**
375     * Causes the current thread to wait until it is signalled or interrupted,
376 dl 1.2 * or the specified deadline elapses.
377 tim 1.1 *
378     * <p>The lock associated with this condition is atomically
379     * released and the current thread becomes disabled for thread scheduling
380     * purposes and lies dormant until <em>one</em> of five things happens:
381     * <ul>
382     * <li>Some other thread invokes the {@link #signal} method for this
383     * <tt>Condition</tt> and the current thread happens to be chosen as the
384     * thread to be awakened; or
385     * <li>Some other thread invokes the {@link #signalAll} method for this
386     * <tt>Condition</tt>; or
387     * <li> Some other thread {@link Thread#interrupt interrupts} the current
388     * thread, and interruption of thread suspension is supported; or
389 dl 1.2 * <li>The specified deadline elapses; or
390 tim 1.1 * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
391     * </ul>
392     *
393     * <p>In all cases, before this method can return the current thread must
394     * re-acquire the lock associated with this condition. When the
395     * thread returns it is <em>guaranteed</em> to hold this lock.
396     *
397     *
398     * <p>If the current thread:
399     * <ul>
400     * <li>has its interrupted status set on entry to this method; or
401     * <li>is {@link Thread#interrupt interrupted} while waiting
402     * and interruption of thread suspension is supported,
403     * </ul>
404     * then {@link InterruptedException} is thrown and the current thread's
405     * interrupted status is cleared. It is not specified, in the first
406     * case, whether or not the test for interruption occurs before the lock
407     * is released.
408     *
409 dl 1.2 *
410     * <p>The return value idicates whether the deadline has elapsed,
411     * which can be used as follows:
412 tim 1.1 * <pre>
413     * synchronized boolean aMethod(Date deadline) {
414     * boolean stillWaiting = true;
415     * while (!conditionBeingWaitedFor) {
416     * if (stillwaiting)
417     * stillWaiting = theCondition.awaitUntil(deadline);
418     * else
419     * return false;
420     * }
421     * // ...
422     * }
423     * </pre>
424     *
425     * <p><b>Implementation Considerations</b>
426     * <p>The current thread is assumed to hold the lock associated with this
427     * <tt>Condition</tt> when this method is called.
428     * It is up to the implementation to determine if this is
429     * the case and if not, how to respond. Typically, an exception will be
430     * thrown (such as {@link IllegalMonitorStateException}) and the
431     * implementation must document that fact.
432     *
433 dholmes 1.5 * <p>An implementation can favour responding to an interrupt over normal
434     * method return in response to a signal, or over indicating the passing
435     * of the specified deadline. In either case the implementation
436     * must ensure that the signal is redirected to another waiting thread, if
437     * there is one.
438     *
439 tim 1.1 *
440     * @param deadline the absolute time to wait until
441 dl 1.2 * @return <tt>false</tt> if the deadline has
442     * elapsed upon return, else <tt>true</tt>.
443 tim 1.1 *
444     * @throws InterruptedException if the current thread is interrupted (and
445     * interruption of thread suspension is supported).
446     */
447 dl 1.4 boolean awaitUntil(Date deadline) throws InterruptedException;
448 tim 1.1
449     /**
450     * Wakes up one waiting thread.
451     *
452     * <p>If any threads are waiting on this condition then one
453     * is selected for waking up. That thread must then re-acquire the
454     * lock before returning from <tt>await</tt>.
455 dl 1.2 **/
456 dl 1.4 void signal();
457 tim 1.1
458     /**
459 dl 1.2 * Wake up all waiting threads.
460 tim 1.1 *
461     * <p>If any threads are waiting on this condition then they are
462     * all woken up. Each thread must re-acquire the lock before it can
463     * return from <tt>await</tt>.
464 dl 1.2 **/
465 dl 1.4 void signalAll();
466 tim 1.1
467     }
468 dholmes 1.5
469    
470    
471 tim 1.1
472    
473    
474