ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/Condition.java
Revision: 1.3
Committed: Mon Jun 23 02:26:16 2003 UTC (20 years, 11 months ago) by brian
Branch: MAIN
Changes since 1.2: +17 -18 lines
Log Message:
Partial javadoc pass

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