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 java.util.concurrent;
008:
009: import java.util.concurrent.locks.*;
010: import java.util.concurrent.atomic.*;
011:
012: /**
013: * A synchronization aid that allows one or more threads to wait until
014: * a set of operations being performed in other threads completes.
015: *
016: * <p>A <tt>CountDownLatch</tt> is initialized with a given
017: * <em>count</em>. The {@link #await await} methods block until the current
018: * {@link #getCount count} reaches zero due to invocations of the
019: * {@link #countDown} method, after which all waiting threads are
020: * released and any subsequent invocations of {@link #await await} return
021: * immediately. This is a one-shot phenomenon -- the count cannot be
022: * reset. If you need a version that resets the count, consider using
023: * a {@link CyclicBarrier}.
024: *
025: * <p>A <tt>CountDownLatch</tt> is a versatile synchronization tool
026: * and can be used for a number of purposes. A
027: * <tt>CountDownLatch</tt> initialized with a count of one serves as a
028: * simple on/off latch, or gate: all threads invoking {@link #await await}
029: * wait at the gate until it is opened by a thread invoking {@link
030: * #countDown}. A <tt>CountDownLatch</tt> initialized to <em>N</em>
031: * can be used to make one thread wait until <em>N</em> threads have
032: * completed some action, or some action has been completed N times.
033: * <p>A useful property of a <tt>CountDownLatch</tt> is that it
034: * doesn't require that threads calling <tt>countDown</tt> wait for
035: * the count to reach zero before proceeding, it simply prevents any
036: * thread from proceeding past an {@link #await await} until all
037: * threads could pass.
038: *
039: * <p><b>Sample usage:</b> Here is a pair of classes in which a group
040: * of worker threads use two countdown latches:
041: * <ul>
042: * <li>The first is a start signal that prevents any worker from proceeding
043: * until the driver is ready for them to proceed;
044: * <li>The second is a completion signal that allows the driver to wait
045: * until all workers have completed.
046: * </ul>
047: *
048: * <pre>
049: * class Driver { // ...
050: * void main() throws InterruptedException {
051: * CountDownLatch startSignal = new CountDownLatch(1);
052: * CountDownLatch doneSignal = new CountDownLatch(N);
053: *
054: * for (int i = 0; i < N; ++i) // create and start threads
055: * new Thread(new Worker(startSignal, doneSignal)).start();
056: *
057: * doSomethingElse(); // don't let run yet
058: * startSignal.countDown(); // let all threads proceed
059: * doSomethingElse();
060: * doneSignal.await(); // wait for all to finish
061: * }
062: * }
063: *
064: * class Worker implements Runnable {
065: * private final CountDownLatch startSignal;
066: * private final CountDownLatch doneSignal;
067: * Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
068: * this.startSignal = startSignal;
069: * this.doneSignal = doneSignal;
070: * }
071: * public void run() {
072: * try {
073: * startSignal.await();
074: * doWork();
075: * doneSignal.countDown();
076: * } catch (InterruptedException ex) {} // return;
077: * }
078: *
079: * void doWork() { ... }
080: * }
081: *
082: * </pre>
083: *
084: * <p>Another typical usage would be to divide a problem into N parts,
085: * describe each part with a Runnable that executes that portion and
086: * counts down on the latch, and queue all the Runnables to an
087: * Executor. When all sub-parts are complete, the coordinating thread
088: * will be able to pass through await. (When threads must repeatedly
089: * count down in this way, instead use a {@link CyclicBarrier}.)
090: *
091: * <pre>
092: * class Driver2 { // ...
093: * void main() throws InterruptedException {
094: * CountDownLatch doneSignal = new CountDownLatch(N);
095: * Executor e = ...
096: *
097: * for (int i = 0; i < N; ++i) // create and start threads
098: * e.execute(new WorkerRunnable(doneSignal, i));
099: *
100: * doneSignal.await(); // wait for all to finish
101: * }
102: * }
103: *
104: * class WorkerRunnable implements Runnable {
105: * private final CountDownLatch doneSignal;
106: * private final int i;
107: * WorkerRunnable(CountDownLatch doneSignal, int i) {
108: * this.doneSignal = doneSignal;
109: * this.i = i;
110: * }
111: * public void run() {
112: * try {
113: * doWork(i);
114: * doneSignal.countDown();
115: * } catch (InterruptedException ex) {} // return;
116: * }
117: *
118: * void doWork() { ... }
119: * }
120: *
121: * </pre>
122: *
123: * @since 1.5
124: * @author Doug Lea
125: */
126: public class CountDownLatch {
127: /**
128: * Synchronization control For CountDownLatch.
129: * Uses AQS state to represent count.
130: */
131: private static final class Sync extends AbstractQueuedSynchronizer {
132: Sync(int count) {
133: setState(count);
134: }
135:
136: int getCount() {
137: return getState();
138: }
139:
140: public int tryAcquireShared(int acquires) {
141: return getState() == 0 ? 1 : -1;
142: }
143:
144: public boolean tryReleaseShared(int releases) {
145: // Decrement count; signal when transition to zero
146: for (;;) {
147: int c = getState();
148: if (c == 0)
149: return false;
150: int nextc = c - 1;
151: if (compareAndSetState(c, nextc))
152: return nextc == 0;
153: }
154: }
155: }
156:
157: private final Sync sync;
158:
159: /**
160: * Constructs a <tt>CountDownLatch</tt> initialized with the given
161: * count.
162: *
163: * @param count the number of times {@link #countDown} must be invoked
164: * before threads can pass through {@link #await}.
165: *
166: * @throws IllegalArgumentException if <tt>count</tt> is less than zero.
167: */
168: public CountDownLatch(int count) {
169: if (count < 0)
170: throw new IllegalArgumentException("count < 0");
171: this .sync = new Sync(count);
172: }
173:
174: /**
175: * Causes the current thread to wait until the latch has counted down to
176: * zero, unless the thread is {@link Thread#interrupt interrupted}.
177: *
178: * <p>If the current {@link #getCount count} is zero then this method
179: * returns immediately.
180: * <p>If the current {@link #getCount count} is greater than zero then
181: * the current thread becomes disabled for thread scheduling
182: * purposes and lies dormant until one of two things happen:
183: * <ul>
184: * <li>The count reaches zero due to invocations of the
185: * {@link #countDown} method; or
186: * <li>Some other thread {@link Thread#interrupt interrupts} the current
187: * thread.
188: * </ul>
189: * <p>If the current thread:
190: * <ul>
191: * <li>has its interrupted status set on entry to this method; or
192: * <li>is {@link Thread#interrupt interrupted} while waiting,
193: * </ul>
194: * then {@link InterruptedException} is thrown and the current thread's
195: * interrupted status is cleared.
196: *
197: * @throws InterruptedException if the current thread is interrupted
198: * while waiting.
199: */
200: public void await() throws InterruptedException {
201: sync.acquireSharedInterruptibly(1);
202: }
203:
204: /**
205: * Causes the current thread to wait until the latch has counted down to
206: * zero, unless the thread is {@link Thread#interrupt interrupted},
207: * or the specified waiting time elapses.
208: *
209: * <p>If the current {@link #getCount count} is zero then this method
210: * returns immediately with the value <tt>true</tt>.
211: *
212: * <p>If the current {@link #getCount count} is greater than zero then
213: * the current thread becomes disabled for thread scheduling
214: * purposes and lies dormant until one of three things happen:
215: * <ul>
216: * <li>The count reaches zero due to invocations of the
217: * {@link #countDown} method; or
218: * <li>Some other thread {@link Thread#interrupt interrupts} the current
219: * thread; or
220: * <li>The specified waiting time elapses.
221: * </ul>
222: * <p>If the count reaches zero then the method returns with the
223: * value <tt>true</tt>.
224: * <p>If the current thread:
225: * <ul>
226: * <li>has its interrupted status set on entry to this method; or
227: * <li>is {@link Thread#interrupt interrupted} while waiting,
228: * </ul>
229: * then {@link InterruptedException} is thrown and the current thread's
230: * interrupted status is cleared.
231: *
232: * <p>If the specified waiting time elapses then the value <tt>false</tt>
233: * is returned.
234: * If the time is
235: * less than or equal to zero, the method will not wait at all.
236: *
237: * @param timeout the maximum time to wait
238: * @param unit the time unit of the <tt>timeout</tt> argument.
239: * @return <tt>true</tt> if the count reached zero and <tt>false</tt>
240: * if the waiting time elapsed before the count reached zero.
241: *
242: * @throws InterruptedException if the current thread is interrupted
243: * while waiting.
244: */
245: public boolean await(long timeout, TimeUnit unit)
246: throws InterruptedException {
247: return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
248: }
249:
250: /**
251: * Decrements the count of the latch, releasing all waiting threads if
252: * the count reaches zero.
253: * <p>If the current {@link #getCount count} is greater than zero then
254: * it is decremented. If the new count is zero then all waiting threads
255: * are re-enabled for thread scheduling purposes.
256: * <p>If the current {@link #getCount count} equals zero then nothing
257: * happens.
258: */
259: public void countDown() {
260: sync.releaseShared(1);
261: }
262:
263: /**
264: * Returns the current count.
265: * <p>This method is typically used for debugging and testing purposes.
266: * @return the current count.
267: */
268: public long getCount() {
269: return sync.getCount();
270: }
271:
272: /**
273: * Returns a string identifying this latch, as well as its state.
274: * The state, in brackets, includes the String
275: * "Count =" followed by the current count.
276: * @return a string identifying this latch, as well as its
277: * state
278: */
279: public String toString() {
280: return super .toString() + "[Count = " + sync.getCount() + "]";
281: }
282:
283: }
|