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