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