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/publicdomain/zero/1.0/
5  */
6 
7 package java.util.concurrent;
8 
9 import java.util.concurrent.locks.AbstractQueuedSynchronizer;
10 
11 /**
12  * A synchronization aid that allows one or more threads to wait until
13  * a set of operations being performed in other threads completes.
14  *
15  * <p>A {@code CountDownLatch} is initialized with a given <em>count</em>.
16  * The {@link #await await} methods block until the current count reaches
17  * zero due to invocations of the {@link #countDown} method, after which
18  * all waiting threads are released and any subsequent invocations of
19  * {@link #await await} return immediately.  This is a one-shot phenomenon
20  * -- the count cannot be reset.  If you need a version that resets the
21  * count, consider using a {@link CyclicBarrier}.
22  *
23  * <p>A {@code CountDownLatch} is a versatile synchronization tool
24  * and can be used for a number of purposes.  A
25  * {@code CountDownLatch} initialized with a count of one serves as a
26  * simple on/off latch, or gate: all threads invoking {@link #await await}
27  * wait at the gate until it is opened by a thread invoking {@link
28  * #countDown}.  A {@code CountDownLatch} initialized to <em>N</em>
29  * can be used to make one thread wait until <em>N</em> threads have
30  * completed some action, or some action has been completed N times.
31  *
32  * <p>A useful property of a {@code CountDownLatch} is that it
33  * doesn't require that threads calling {@code countDown} wait for
34  * the count to reach zero before proceeding, it simply prevents any
35  * thread from proceeding past an {@link #await await} until all
36  * threads could pass.
37  *
38  * <p><b>Sample usage:</b> Here is a pair of classes in which a group
39  * of worker threads use two countdown latches:
40  * <ul>
41  * <li>The first is a start signal that prevents any worker from proceeding
42  * until the driver is ready for them to proceed;
43  * <li>The second is a completion signal that allows the driver to wait
44  * until all workers have completed.
45  * </ul>
46  *
47  * <pre> {@code
48  * class Driver { // ...
49  *   void main() throws InterruptedException {
50  *     CountDownLatch startSignal = new CountDownLatch(1);
51  *     CountDownLatch doneSignal = new CountDownLatch(N);
52  *
53  *     for (int i = 0; i < N; ++i) // create and start threads
54  *       new Thread(new Worker(startSignal, doneSignal)).start();
55  *
56  *     doSomethingElse();            // don't let run yet
57  *     startSignal.countDown();      // let all threads proceed
58  *     doSomethingElse();
59  *     doneSignal.await();           // wait for all to finish
60  *   }
61  * }
62  *
63  * class Worker implements Runnable {
64  *   private final CountDownLatch startSignal;
65  *   private final CountDownLatch doneSignal;
66  *   Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
67  *     this.startSignal = startSignal;
68  *     this.doneSignal = doneSignal;
69  *   }
70  *   public void run() {
71  *     try {
72  *       startSignal.await();
73  *       doWork();
74  *       doneSignal.countDown();
75  *     } catch (InterruptedException ex) {} // return;
76  *   }
77  *
78  *   void doWork() { ... }
79  * }}</pre>
80  *
81  * <p>Another typical usage would be to divide a problem into N parts,
82  * describe each part with a Runnable that executes that portion and
83  * counts down on the latch, and queue all the Runnables to an
84  * Executor.  When all sub-parts are complete, the coordinating thread
85  * will be able to pass through await. (When threads must repeatedly
86  * count down in this way, instead use a {@link CyclicBarrier}.)
87  *
88  * <pre> {@code
89  * class Driver2 { // ...
90  *   void main() throws InterruptedException {
91  *     CountDownLatch doneSignal = new CountDownLatch(N);
92  *     Executor e = ...
93  *
94  *     for (int i = 0; i < N; ++i) // create and start threads
95  *       e.execute(new WorkerRunnable(doneSignal, i));
96  *
97  *     doneSignal.await();           // wait for all to finish
98  *   }
99  * }
100  *
101  * class WorkerRunnable implements Runnable {
102  *   private final CountDownLatch doneSignal;
103  *   private final int i;
104  *   WorkerRunnable(CountDownLatch doneSignal, int i) {
105  *     this.doneSignal = doneSignal;
106  *     this.i = i;
107  *   }
108  *   public void run() {
109  *     try {
110  *       doWork(i);
111  *       doneSignal.countDown();
112  *     } catch (InterruptedException ex) {} // return;
113  *   }
114  *
115  *   void doWork() { ... }
116  * }}</pre>
117  *
118  * <p>Memory consistency effects: Until the count reaches
119  * zero, actions in a thread prior to calling
120  * {@code countDown()}
121  * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
122  * actions following a successful return from a corresponding
123  * {@code await()} in another thread.
124  *
125  * @since 1.5
126  * @author Doug Lea
127  */
128 public class CountDownLatch {
129     /**
130      * Synchronization control For CountDownLatch.
131      * Uses AQS state to represent count.
132      */
133     private static final class Sync extends AbstractQueuedSynchronizer {
134         private static final long serialVersionUID = 4982264981922014374L;
135 
Sync(int count)136         Sync(int count) {
137             setState(count);
138         }
139 
getCount()140         int getCount() {
141             return getState();
142         }
143 
tryAcquireShared(int acquires)144         protected int tryAcquireShared(int acquires) {
145             return (getState() == 0) ? 1 : -1;
146         }
147 
tryReleaseShared(int releases)148         protected boolean tryReleaseShared(int releases) {
149             // Decrement count; signal when transition to zero
150             for (;;) {
151                 int c = getState();
152                 if (c == 0)
153                     return false;
154                 int nextc = c - 1;
155                 if (compareAndSetState(c, nextc))
156                     return nextc == 0;
157             }
158         }
159     }
160 
161     private final Sync sync;
162 
163     /**
164      * Constructs a {@code CountDownLatch} initialized with the given count.
165      *
166      * @param count the number of times {@link #countDown} must be invoked
167      *        before threads can pass through {@link #await}
168      * @throws IllegalArgumentException if {@code count} is negative
169      */
CountDownLatch(int count)170     public CountDownLatch(int count) {
171         if (count < 0) throw new IllegalArgumentException("count < 0");
172         this.sync = new Sync(count);
173     }
174 
175     /**
176      * Causes the current thread to wait until the latch has counted down to
177      * zero, unless the thread is {@linkplain Thread#interrupt interrupted}.
178      *
179      * <p>If the current count is zero then this method returns immediately.
180      *
181      * <p>If the current count is greater than zero then the current
182      * thread becomes disabled for thread scheduling purposes and lies
183      * dormant until one of two things happen:
184      * <ul>
185      * <li>The count reaches zero due to invocations of the
186      * {@link #countDown} method; or
187      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
188      * the current thread.
189      * </ul>
190      *
191      * <p>If the current thread:
192      * <ul>
193      * <li>has its interrupted status set on entry to this method; or
194      * <li>is {@linkplain Thread#interrupt interrupted} while waiting,
195      * </ul>
196      * then {@link InterruptedException} is thrown and the current thread's
197      * interrupted status is cleared.
198      *
199      * @throws InterruptedException if the current thread is interrupted
200      *         while waiting
201      */
await()202     public void await() throws InterruptedException {
203         sync.acquireSharedInterruptibly(1);
204     }
205 
206     /**
207      * Causes the current thread to wait until the latch has counted down to
208      * zero, unless the thread is {@linkplain Thread#interrupt interrupted},
209      * or the specified waiting time elapses.
210      *
211      * <p>If the current count is zero then this method returns immediately
212      * with the value {@code true}.
213      *
214      * <p>If the current count is greater than zero then the current
215      * thread becomes disabled for thread scheduling purposes and lies
216      * dormant until one of three things happen:
217      * <ul>
218      * <li>The count reaches zero due to invocations of the
219      * {@link #countDown} method; or
220      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
221      * the current thread; or
222      * <li>The specified waiting time elapses.
223      * </ul>
224      *
225      * <p>If the count reaches zero then the method returns with the
226      * value {@code true}.
227      *
228      * <p>If the current thread:
229      * <ul>
230      * <li>has its interrupted status set on entry to this method; or
231      * <li>is {@linkplain Thread#interrupt interrupted} while waiting,
232      * </ul>
233      * then {@link InterruptedException} is thrown and the current thread's
234      * interrupted status is cleared.
235      *
236      * <p>If the specified waiting time elapses then the value {@code false}
237      * is returned.  If the time is less than or equal to zero, the method
238      * will not wait at all.
239      *
240      * @param timeout the maximum time to wait
241      * @param unit the time unit of the {@code timeout} argument
242      * @return {@code true} if the count reached zero and {@code false}
243      *         if the waiting time elapsed before the count reached zero
244      * @throws InterruptedException if the current thread is interrupted
245      *         while waiting
246      */
await(long timeout, TimeUnit unit)247     public boolean await(long timeout, TimeUnit unit)
248         throws InterruptedException {
249         return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
250     }
251 
252     /**
253      * Decrements the count of the latch, releasing all waiting threads if
254      * the count reaches zero.
255      *
256      * <p>If the current count is greater than zero then it is decremented.
257      * If the new count is zero then all waiting threads are re-enabled for
258      * thread scheduling purposes.
259      *
260      * <p>If the current count equals zero then nothing happens.
261      */
countDown()262     public void countDown() {
263         sync.releaseShared(1);
264     }
265 
266     /**
267      * Returns the current count.
268      *
269      * <p>This method is typically used for debugging and testing purposes.
270      *
271      * @return the current count
272      */
getCount()273     public long getCount() {
274         return sync.getCount();
275     }
276 
277     /**
278      * Returns a string identifying this latch, as well as its state.
279      * The state, in brackets, includes the String {@code "Count ="}
280      * followed by the current count.
281      *
282      * @return a string identifying this latch, as well as its state
283      */
toString()284     public String toString() {
285         return super.toString() + "[Count = " + sync.getCount() + "]";
286     }
287 }
288