001: /*
002: * Written by Doug Lea with assistance from members of JCP JSR-166
003: * Expert Group and released to the public domain, as explained at
004: * http://creativecommons.org/licenses/publicdomain
005: */
006:
007: package org.apache.beehive.netui.util.internal.concurrent;
008:
009: import java.util.Date;
010:
011: /**
012: * <tt>Condition</tt> factors out the <tt>Object</tt> monitor
013: * methods ({@link Object#wait() wait}, {@link Object#notify notify}
014: * and {@link Object#notifyAll notifyAll}) into distinct objects to
015: * give the effect of having multiple wait-sets per object, by
016: * combining them with the use of arbitrary {@link Lock} implementations.
017: * Where a <tt>Lock</tt> replaces the use of <tt>synchronized</tt> methods
018: * and statements, a <tt>Condition</tt> replaces the use of the Object
019: * monitor methods.
020: *
021: * <p>Conditions (also known as <em>condition queues</em> or
022: * <em>condition variables</em>) provide a means for one thread to
023: * suspend execution (to "wait") until notified by another
024: * thread that some state condition may now be true. Because access
025: * to this shared state information occurs in different threads, it
026: * must be protected, so a lock of some form is associated with the
027: * condition. The key property that waiting for a condition provides
028: * is that it <em>atomically</em> releases the associated lock and
029: * suspends the current thread, just like <tt>Object.wait</tt>.
030: *
031: * <p>A <tt>Condition</tt> instance is intrinsically bound to a lock.
032: * To obtain a <tt>Condition</tt> instance for a particular {@link Lock}
033: * instance use its {@link Lock#newCondition newCondition()} method.
034: *
035: * <p>As an example, suppose we have a bounded buffer which supports
036: * <tt>put</tt> and <tt>take</tt> methods. If a
037: * <tt>take</tt> is attempted on an empty buffer, then the thread will block
038: * until an item becomes available; if a <tt>put</tt> is attempted on a
039: * full buffer, then the thread will block until a space becomes available.
040: * We would like to keep waiting <tt>put</tt> threads and <tt>take</tt>
041: * threads in separate wait-sets so that we can use the optimization of
042: * only notifying a single thread at a time when items or spaces become
043: * available in the buffer. This can be achieved using two
044: * {@link Condition} instances.
045: * <pre>
046: * class BoundedBuffer {
047: * <b>final Lock lock = new ReentrantLock();</b>
048: * final Condition notFull = <b>lock.newCondition(); </b>
049: * final Condition notEmpty = <b>lock.newCondition(); </b>
050: *
051: * final Object[] items = new Object[100];
052: * int putptr, takeptr, count;
053: *
054: * public void put(Object x) throws InterruptedException {
055: * <b>lock.lock();
056: * try {</b>
057: * while (count == items.length)
058: * <b>notFull.await();</b>
059: * items[putptr] = x;
060: * if (++putptr == items.length) putptr = 0;
061: * ++count;
062: * <b>notEmpty.signal();</b>
063: * <b>} finally {
064: * lock.unlock();
065: * }</b>
066: * }
067: *
068: * public Object take() throws InterruptedException {
069: * <b>lock.lock();
070: * try {</b>
071: * while (count == 0)
072: * <b>notEmpty.await();</b>
073: * Object x = items[takeptr];
074: * if (++takeptr == items.length) takeptr = 0;
075: * --count;
076: * <b>notFull.signal();</b>
077: * return x;
078: * <b>} finally {
079: * lock.unlock();
080: * }</b>
081: * }
082: * }
083: * </pre>
084: *
085: * (The {@link org.apache.beehive.netui.util.concurrent.ArrayBlockingQueue} class provides
086: * this functionality, so there is no reason to implement this
087: * sample usage class.)
088: *
089: * <p>A <tt>Condition</tt> implementation can provide behavior and semantics
090: * that is
091: * different from that of the <tt>Object</tt> monitor methods, such as
092: * guaranteed ordering for notifications, or not requiring a lock to be held
093: * when performing notifications.
094: * If an implementation provides such specialized semantics then the
095: * implementation must document those semantics.
096: *
097: * <p>Note that <tt>Condition</tt> instances are just normal objects and can
098: * themselves be used as the target in a <tt>synchronized</tt> statement,
099: * and can have their own monitor {@link Object#wait wait} and
100: * {@link Object#notify notification} methods invoked.
101: * Acquiring the monitor lock of a <tt>Condition</tt> instance, or using its
102: * monitor methods, has no specified relationship with acquiring the
103: * {@link Lock} associated with that <tt>Condition</tt> or the use of its
104: * {@link #await waiting} and {@link #signal signalling} methods.
105: * It is recommended that to avoid confusion you never use <tt>Condition</tt>
106: * instances in this way, except perhaps within their own implementation.
107: *
108: * <p>Except where noted, passing a <tt>null</tt> value for any parameter
109: * will result in a {@link NullPointerException} being thrown.
110: *
111: * <h3>Implementation Considerations</h3>
112: *
113: * <p>When waiting upon a <tt>Condition</tt>, a "<em>spurious
114: * wakeup</em>" is permitted to occur, in
115: * general, as a concession to the underlying platform semantics.
116: * This has little practical impact on most application programs as a
117: * <tt>Condition</tt> should always be waited upon in a loop, testing
118: * the state predicate that is being waited for. An implementation is
119: * free to remove the possibility of spurious wakeups but it is
120: * recommended that applications programmers always assume that they can
121: * occur and so always wait in a loop.
122: *
123: * <p>The three forms of condition waiting
124: * (interruptible, non-interruptible, and timed) may differ in their ease of
125: * implementation on some platforms and in their performance characteristics.
126: * In particular, it may be difficult to provide these features and maintain
127: * specific semantics such as ordering guarantees.
128: * Further, the ability to interrupt the actual suspension of the thread may
129: * not always be feasible to implement on all platforms.
130: * <p>Consequently, an implementation is not required to define exactly the
131: * same guarantees or semantics for all three forms of waiting, nor is it
132: * required to support interruption of the actual suspension of the thread.
133: * <p>An implementation is required to
134: * clearly document the semantics and guarantees provided by each of the
135: * waiting methods, and when an implementation does support interruption of
136: * thread suspension then it must obey the interruption semantics as defined
137: * in this interface.
138: * <p>As interruption generally implies cancellation, and checks for
139: * interruption are often infrequent, an implementation can favor responding
140: * to an interrupt over normal method return. This is true even if it can be
141: * shown that the interrupt occurred after another action may have unblocked
142: * the thread. An implementation should document this behavior.
143: *
144: *
145: * @since 1.5
146: * @author Doug Lea
147: */
148: interface Condition {
149:
150: /**
151: * Causes the current thread to wait until it is signalled or
152: * {@link Thread#interrupt interrupted}.
153: *
154: * <p>The lock associated with this <tt>Condition</tt> is atomically
155: * released and the current thread becomes disabled for thread scheduling
156: * purposes and lies dormant until <em>one</em> of four things happens:
157: * <ul>
158: * <li>Some other thread invokes the {@link #signal} method for this
159: * <tt>Condition</tt> and the current thread happens to be chosen as the
160: * thread to be awakened; or
161: * <li>Some other thread invokes the {@link #signalAll} method for this
162: * <tt>Condition</tt>; or
163: * <li>Some other thread {@link Thread#interrupt interrupts} the current
164: * thread, and interruption of thread suspension is supported; or
165: * <li>A "<em>spurious wakeup</em>" occurs
166: * </ul>
167: *
168: * <p>In all cases, before this method can return the current thread must
169: * re-acquire the lock associated with this condition. When the
170: * thread returns it is <em>guaranteed</em> to hold this lock.
171: *
172: * <p>If the current thread:
173: * <ul>
174: * <li>has its interrupted status set on entry to this method; or
175: * <li>is {@link Thread#interrupt interrupted} while waiting
176: * and interruption of thread suspension is supported,
177: * </ul>
178: * then {@link InterruptedException} is thrown and the current thread's
179: * interrupted status is cleared. It is not specified, in the first
180: * case, whether or not the test for interruption occurs before the lock
181: * is released.
182: *
183: * <p><b>Implementation Considerations</b>
184: * <p>The current thread is assumed to hold the lock associated with this
185: * <tt>Condition</tt> when this method is called.
186: * It is up to the implementation to determine if this is
187: * the case and if not, how to respond. Typically, an exception will be
188: * thrown (such as {@link IllegalMonitorStateException}) and the
189: * implementation must document that fact.
190: *
191: * <p>An implementation can favor responding to an interrupt over normal
192: * method return in response to a signal. In that case the implementation
193: * must ensure that the signal is redirected to another waiting thread, if
194: * there is one.
195: *
196: * @throws InterruptedException if the current thread is interrupted (and
197: * interruption of thread suspension is supported).
198: **/
199: void await() throws InterruptedException;
200:
201: /**
202: * Causes the current thread to wait until it is signalled.
203: *
204: * <p>The lock associated with this condition is atomically
205: * released and the current thread becomes disabled for thread scheduling
206: * purposes and lies dormant until <em>one</em> of three things happens:
207: * <ul>
208: * <li>Some other thread invokes the {@link #signal} method for this
209: * <tt>Condition</tt> and the current thread happens to be chosen as the
210: * thread to be awakened; or
211: * <li>Some other thread invokes the {@link #signalAll} method for this
212: * <tt>Condition</tt>; or
213: * <li>A "<em>spurious wakeup</em>" occurs
214: * </ul>
215: *
216: * <p>In all cases, before this method can return the current thread must
217: * re-acquire the lock associated with this condition. When the
218: * thread returns it is <em>guaranteed</em> to hold this lock.
219: *
220: * <p>If the current thread's interrupted status is set when it enters
221: * this method, or it is {@link Thread#interrupt interrupted}
222: * while waiting, it will continue to wait until signalled. When it finally
223: * returns from this method its interrupted status will still
224: * be set.
225: *
226: * <p><b>Implementation Considerations</b>
227: * <p>The current thread is assumed to hold the lock associated with this
228: * <tt>Condition</tt> when this method is called.
229: * It is up to the implementation to determine if this is
230: * the case and if not, how to respond. Typically, an exception will be
231: * thrown (such as {@link IllegalMonitorStateException}) and the
232: * implementation must document that fact.
233: *
234: **/
235: void awaitUninterruptibly();
236:
237: // /**
238: // * Causes the current thread to wait until it is signalled or interrupted,
239: // * or the specified waiting time elapses.
240: // *
241: // * <p>The lock associated with this condition is atomically
242: // * released and the current thread becomes disabled for thread scheduling
243: // * purposes and lies dormant until <em>one</em> of five things happens:
244: // * <ul>
245: // * <li>Some other thread invokes the {@link #signal} method for this
246: // * <tt>Condition</tt> and the current thread happens to be chosen as the
247: // * thread to be awakened; or
248: // * <li>Some other thread invokes the {@link #signalAll} method for this
249: // * <tt>Condition</tt>; or
250: // * <li>Some other thread {@link Thread#interrupt interrupts} the current
251: // * thread, and interruption of thread suspension is supported; or
252: // * <li>The specified waiting time elapses; or
253: // * <li>A "<em>spurious wakeup</em>" occurs.
254: // * </ul>
255: // *
256: // * <p>In all cases, before this method can return the current thread must
257: // * re-acquire the lock associated with this condition. When the
258: // * thread returns it is <em>guaranteed</em> to hold this lock.
259: // *
260: // * <p>If the current thread:
261: // * <ul>
262: // * <li>has its interrupted status set on entry to this method; or
263: // * <li>is {@link Thread#interrupt interrupted} while waiting
264: // * and interruption of thread suspension is supported,
265: // * </ul>
266: // * then {@link InterruptedException} is thrown and the current thread's
267: // * interrupted status is cleared. It is not specified, in the first
268: // * case, whether or not the test for interruption occurs before the lock
269: // * is released.
270: // *
271: // * <p>The method returns an estimate of the number of nanoseconds
272: // * remaining to wait given the supplied <tt>nanosTimeout</tt>
273: // * value upon return, or a value less than or equal to zero if it
274: // * timed out. This value can be used to determine whether and how
275: // * long to re-wait in cases where the wait returns but an awaited
276: // * condition still does not hold. Typical uses of this method take
277: // * the following form:
278: // *
279: // * <pre>
280: // * synchronized boolean aMethod(long timeout, TimeUnit unit) {
281: // * long nanosTimeout = unit.toNanos(timeout);
282: // * while (!conditionBeingWaitedFor) {
283: // * if (nanosTimeout > 0)
284: // * nanosTimeout = theCondition.awaitNanos(nanosTimeout);
285: // * else
286: // * return false;
287: // * }
288: // * // ...
289: // * }
290: // * </pre>
291: // *
292: // * <p> Design note: This method requires a nanosecond argument so
293: // * as to avoid truncation errors in reporting remaining times.
294: // * Such precision loss would make it difficult for programmers to
295: // * ensure that total waiting times are not systematically shorter
296: // * than specified when re-waits occur.
297: // *
298: // * <p><b>Implementation Considerations</b>
299: // * <p>The current thread is assumed to hold the lock associated with this
300: // * <tt>Condition</tt> when this method is called.
301: // * It is up to the implementation to determine if this is
302: // * the case and if not, how to respond. Typically, an exception will be
303: // * thrown (such as {@link IllegalMonitorStateException}) and the
304: // * implementation must document that fact.
305: // *
306: // * <p>An implementation can favor responding to an interrupt over normal
307: // * method return in response to a signal, or over indicating the elapse
308: // * of the specified waiting time. In either case the implementation
309: // * must ensure that the signal is redirected to another waiting thread, if
310: // * there is one.
311: // *
312: // * @param nanosTimeout the maximum time to wait, in nanoseconds
313: // * @return A value less than or equal to zero if the wait has
314: // * timed out; otherwise an estimate, that
315: // * is strictly less than the <tt>nanosTimeout</tt> argument,
316: // * of the time still remaining when this method returned.
317: // *
318: // * @throws InterruptedException if the current thread is interrupted (and
319: // * interruption of thread suspension is supported).
320: // */
321: // long awaitNanos(long nanosTimeout) throws InterruptedException;
322:
323: /**
324: * Causes the current thread to wait until it is signalled or interrupted,
325: * or the specified waiting time elapses. This method is behaviorally
326: * equivalent to:<br>
327: * <pre>
328: * awaitNanos(unit.toNanos(time)) > 0
329: * </pre>
330: * @param time the maximum time to wait
331: * @param unit the time unit of the <tt>time</tt> argument.
332: * @return <tt>false</tt> if the waiting time detectably elapsed
333: * before return from the method, else <tt>true</tt>.
334: * @throws InterruptedException if the current thread is interrupted (and
335: * interruption of thread suspension is supported).
336: */
337: boolean await(long time, TimeUnit unit) throws InterruptedException;
338:
339: /**
340: * Causes the current thread to wait until it is signalled or interrupted,
341: * or the specified deadline elapses.
342: *
343: * <p>The lock associated with this condition is atomically
344: * released and the current thread becomes disabled for thread scheduling
345: * purposes and lies dormant until <em>one</em> of five things happens:
346: * <ul>
347: * <li>Some other thread invokes the {@link #signal} method for this
348: * <tt>Condition</tt> and the current thread happens to be chosen as the
349: * thread to be awakened; or
350: * <li>Some other thread invokes the {@link #signalAll} method for this
351: * <tt>Condition</tt>; or
352: * <li>Some other thread {@link Thread#interrupt interrupts} the current
353: * thread, and interruption of thread suspension is supported; or
354: * <li>The specified deadline elapses; or
355: * <li>A "<em>spurious wakeup</em>" occurs.
356: * </ul>
357: *
358: * <p>In all cases, before this method can return the current thread must
359: * re-acquire the lock associated with this condition. When the
360: * thread returns it is <em>guaranteed</em> to hold this lock.
361: *
362: *
363: * <p>If the current thread:
364: * <ul>
365: * <li>has its interrupted status set on entry to this method; or
366: * <li>is {@link Thread#interrupt interrupted} while waiting
367: * and interruption of thread suspension is supported,
368: * </ul>
369: * then {@link InterruptedException} is thrown and the current thread's
370: * interrupted status is cleared. It is not specified, in the first
371: * case, whether or not the test for interruption occurs before the lock
372: * is released.
373: *
374: *
375: * <p>The return value indicates whether the deadline has elapsed,
376: * which can be used as follows:
377: * <pre>
378: * synchronized boolean aMethod(Date deadline) {
379: * boolean stillWaiting = true;
380: * while (!conditionBeingWaitedFor) {
381: * if (stillwaiting)
382: * stillWaiting = theCondition.awaitUntil(deadline);
383: * else
384: * return false;
385: * }
386: * // ...
387: * }
388: * </pre>
389: *
390: * <p><b>Implementation Considerations</b>
391: * <p>The current thread is assumed to hold the lock associated with this
392: * <tt>Condition</tt> when this method is called.
393: * It is up to the implementation to determine if this is
394: * the case and if not, how to respond. Typically, an exception will be
395: * thrown (such as {@link IllegalMonitorStateException}) and the
396: * implementation must document that fact.
397: *
398: * <p>An implementation can favor responding to an interrupt over normal
399: * method return in response to a signal, or over indicating the passing
400: * of the specified deadline. In either case the implementation
401: * must ensure that the signal is redirected to another waiting thread, if
402: * there is one.
403: *
404: *
405: * @param deadline the absolute time to wait until
406: * @return <tt>false</tt> if the deadline has
407: * elapsed upon return, else <tt>true</tt>.
408: *
409: * @throws InterruptedException if the current thread is interrupted (and
410: * interruption of thread suspension is supported).
411: */
412: boolean awaitUntil(Date deadline) throws InterruptedException;
413:
414: /**
415: * Wakes up one waiting thread.
416: *
417: * <p>If any threads are waiting on this condition then one
418: * is selected for waking up. That thread must then re-acquire the
419: * lock before returning from <tt>await</tt>.
420: **/
421: void signal();
422:
423: /**
424: * Wakes up all waiting threads.
425: *
426: * <p>If any threads are waiting on this condition then they are
427: * all woken up. Each thread must re-acquire the lock before it can
428: * return from <tt>await</tt>.
429: **/
430: void signalAll();
431:
432: }
|