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, 10 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

# Content
1 /*
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 package java.util.concurrent;
8 import java.util.Date;
9
10 /**
11 * <tt>Condition</tt> factors out the <tt>Object</tt> monitor
12 * 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 * monitor. It also generalises the monitor methods to allow them to
16 * be used with arbitrary {@link Lock} implementations when needed.
17 *
18 * <p>Conditions (also known as <em>condition queues</em> or
19 * <em>condition variables</em>) provide
20 * a means for one thread to suspend execution (to &quot;wait&quot;) until
21 * 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 * property that waiting for a condition provides is that it
26 * <em>atomically</em> releases the associated lock and suspends the current
27 * thread, just like <tt>Object.wait</tt>.
28 *
29 * <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 * 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 * <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 * 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 * only notifying a single thread at a time when items or spaces become
45 * 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 * monitor methods, has no specified relationship with acquiring the
135 * {@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 * <p>When waiting upon a <tt>Condition</tt>, a &quot;<em>spurious
146 * 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 * the state predicate that is being waited for. An implementation is
151 * 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 * <p>The three forms of condition waiting
156 * (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 * <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 *
176 *
177 * @since 1.5
178 * @spec JSR-166
179 * @revised $Date: 2003/06/26 05:42:58 $
180 * @editor $Author: dholmes $
181 * @author Doug Lea
182 */
183 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 * <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 * @throws InterruptedException if the current thread is interrupted (and
232 * interruption of thread suspension is supported).
233 **/
234 void await() throws InterruptedException;
235
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 **/
270 void awaitUninterruptibly();
271
272 /**
273 * Causes the current thread to wait until it is signalled or interrupted,
274 * 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 * <p>The method returns an estimate of the number of nanoseconds
307 * remaining to wait given the supplied <tt>nanosTimeout</tt>
308 * 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 * 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 * <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 *
347 * @param nanosTimeout the maximum time to wait, in nanoseconds
348 * @return A value less than or equal to zero if the wait has
349 * timed out; otherwise an estimate, that
350 * 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 long awaitNanos(long nanosTimeout) throws InterruptedException;
357
358 /**
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 * @throws InterruptedException if the current thread is interrupted (and
370 * interruption of thread suspension is supported).
371 */
372 boolean await(long time, TimeUnit unit) throws InterruptedException;
373
374 /**
375 * Causes the current thread to wait until it is signalled or interrupted,
376 * or the specified deadline elapses.
377 *
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 * <li>The specified deadline elapses; or
390 * <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 *
410 * <p>The return value idicates whether the deadline has elapsed,
411 * which can be used as follows:
412 * <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 * <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 *
440 * @param deadline the absolute time to wait until
441 * @return <tt>false</tt> if the deadline has
442 * elapsed upon return, else <tt>true</tt>.
443 *
444 * @throws InterruptedException if the current thread is interrupted (and
445 * interruption of thread suspension is supported).
446 */
447 boolean awaitUntil(Date deadline) throws InterruptedException;
448
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 **/
456 void signal();
457
458 /**
459 * Wake up all waiting threads.
460 *
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 **/
465 void signalAll();
466
467 }
468
469
470
471
472
473
474