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