KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > util > internal > concurrent > Condition


1 /*
2  * Written by Doug Lea with assistance from members of JCP JSR-166
3  * Expert Group and released to the public domain, as explained at
4  * http://creativecommons.org/licenses/publicdomain
5  */

6
7 package org.apache.beehive.netui.util.internal.concurrent;
8
9 import java.util.Date JavaDoc;
10
11 /**
12  * <tt>Condition</tt> factors out the <tt>Object</tt> monitor
13  * methods ({@link Object#wait() wait}, {@link Object#notify notify}
14  * and {@link Object#notifyAll notifyAll}) into distinct objects to
15  * give the effect of having multiple wait-sets per object, by
16  * combining them with the use of arbitrary {@link Lock} implementations.
17  * Where a <tt>Lock</tt> replaces the use of <tt>synchronized</tt> methods
18  * and statements, a <tt>Condition</tt> replaces the use of the Object
19  * monitor methods.
20  *
21  * <p>Conditions (also known as <em>condition queues</em> or
22  * <em>condition variables</em>) provide a means for one thread to
23  * suspend execution (to &quot;wait&quot;) until notified by another
24  * thread that some state condition may now be true. Because access
25  * to this shared state information occurs in different threads, it
26  * must be protected, so a lock of some form is associated with the
27  * condition. The key property that waiting for a condition provides
28  * is that it <em>atomically</em> releases the associated lock and
29  * suspends the current thread, just like <tt>Object.wait</tt>.
30  *
31  * <p>A <tt>Condition</tt> instance is intrinsically bound to a lock.
32  * To obtain a <tt>Condition</tt> instance for a particular {@link Lock}
33  * instance use its {@link Lock#newCondition newCondition()} method.
34  *
35  * <p>As an example, suppose we have a bounded buffer which supports
36  * <tt>put</tt> and <tt>take</tt> methods. If a
37  * <tt>take</tt> is attempted on an empty buffer, then the thread will block
38  * until an item becomes available; if a <tt>put</tt> is attempted on a
39  * full buffer, then the thread will block until a space becomes available.
40  * We would like to keep waiting <tt>put</tt> threads and <tt>take</tt>
41  * threads in separate wait-sets so that we can use the optimization of
42  * only notifying a single thread at a time when items or spaces become
43  * available in the buffer. This can be achieved using two
44  * {@link Condition} instances.
45  * <pre>
46  * class BoundedBuffer {
47  * <b>final Lock lock = new ReentrantLock();</b>
48  * final Condition notFull = <b>lock.newCondition(); </b>
49  * final Condition notEmpty = <b>lock.newCondition(); </b>
50  *
51  * final Object[] items = new Object[100];
52  * int putptr, takeptr, count;
53  *
54  * public void put(Object x) throws InterruptedException {
55  * <b>lock.lock();
56  * try {</b>
57  * while (count == items.length)
58  * <b>notFull.await();</b>
59  * items[putptr] = x;
60  * if (++putptr == items.length) putptr = 0;
61  * ++count;
62  * <b>notEmpty.signal();</b>
63  * <b>} finally {
64  * lock.unlock();
65  * }</b>
66  * }
67  *
68  * public Object take() throws InterruptedException {
69  * <b>lock.lock();
70  * try {</b>
71  * while (count == 0)
72  * <b>notEmpty.await();</b>
73  * Object x = items[takeptr];
74  * if (++takeptr == items.length) takeptr = 0;
75  * --count;
76  * <b>notFull.signal();</b>
77  * return x;
78  * <b>} finally {
79  * lock.unlock();
80  * }</b>
81  * }
82  * }
83  * </pre>
84  *
85  * (The {@link org.apache.beehive.netui.util.concurrent.ArrayBlockingQueue} class provides
86  * this functionality, so there is no reason to implement this
87  * sample usage class.)
88  *
89  * <p>A <tt>Condition</tt> implementation can provide behavior and semantics
90  * that is
91  * different from that of the <tt>Object</tt> monitor methods, such as
92  * guaranteed ordering for notifications, or not requiring a lock to be held
93  * when performing notifications.
94  * If an implementation provides such specialized semantics then the
95  * implementation must document those semantics.
96  *
97  * <p>Note that <tt>Condition</tt> instances are just normal objects and can
98  * themselves be used as the target in a <tt>synchronized</tt> statement,
99  * 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 &quot;<em>spurious
114  * wakeup</em>&quot; 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 &quot;<em>spurious wakeup</em>&quot; 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 JavaDoc;
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 &quot;<em>spurious wakeup</em>&quot; 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 &quot;<em>spurious wakeup</em>&quot; 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 &gt; 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)) &gt; 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 JavaDoc;
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 &quot;<em>spurious wakeup</em>&quot; 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 JavaDoc deadline) throws InterruptedException JavaDoc;
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 }
433
Popular Tags