Source for java.util.concurrent.CountDownLatch

   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/licenses/publicdomain
   5:  */
   6: 
   7: package java.util.concurrent;
   8: import java.util.concurrent.locks.*;
   9: import java.util.concurrent.atomic.*;
  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>
  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:  * }
  80:  *
  81:  * </pre>
  82:  *
  83:  * <p>Another typical usage would be to divide a problem into N parts,
  84:  * describe each part with a Runnable that executes that portion and
  85:  * counts down on the latch, and queue all the Runnables to an
  86:  * Executor.  When all sub-parts are complete, the coordinating thread
  87:  * will be able to pass through await. (When threads must repeatedly
  88:  * count down in this way, instead use a {@link CyclicBarrier}.)
  89:  *
  90:  * <pre>
  91:  * class Driver2 { // ...
  92:  *   void main() throws InterruptedException {
  93:  *     CountDownLatch doneSignal = new CountDownLatch(N);
  94:  *     Executor e = ...
  95:  *
  96:  *     for (int i = 0; i < N; ++i) // create and start threads
  97:  *       e.execute(new WorkerRunnable(doneSignal, i));
  98:  *
  99:  *     doneSignal.await();           // wait for all to finish
 100:  *   }
 101:  * }
 102:  *
 103:  * class WorkerRunnable implements Runnable {
 104:  *   private final CountDownLatch doneSignal;
 105:  *   private final int i;
 106:  *   WorkerRunnable(CountDownLatch doneSignal, int i) {
 107:  *      this.doneSignal = doneSignal;
 108:  *      this.i = i;
 109:  *   }
 110:  *   public void run() {
 111:  *      try {
 112:  *        doWork(i);
 113:  *        doneSignal.countDown();
 114:  *      } catch (InterruptedException ex) {} // return;
 115:  *   }
 116:  *
 117:  *   void doWork() { ... }
 118:  * }
 119:  *
 120:  * </pre>
 121:  *
 122:  * <p>Memory consistency effects: Actions in a thread prior to calling
 123:  * {@code countDown()}
 124:  * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
 125:  * actions following a successful return from a corresponding
 126:  * {@code await()} in another thread.
 127:  *
 128:  * @since 1.5
 129:  * @author Doug Lea
 130:  */
 131: public class CountDownLatch {
 132:     /**
 133:      * Synchronization control For CountDownLatch.
 134:      * Uses AQS state to represent count.
 135:      */
 136:     private static final class Sync extends AbstractQueuedSynchronizer {
 137:         private static final long serialVersionUID = 4982264981922014374L;
 138: 
 139:         Sync(int count) {
 140:             setState(count);
 141:         }
 142: 
 143:         int getCount() {
 144:             return getState();
 145:         }
 146: 
 147:         public int tryAcquireShared(int acquires) {
 148:             return getState() == 0? 1 : -1;
 149:         }
 150: 
 151:         public boolean tryReleaseShared(int releases) {
 152:             // Decrement count; signal when transition to zero
 153:             for (;;) {
 154:                 int c = getState();
 155:                 if (c == 0)
 156:                     return false;
 157:                 int nextc = c-1;
 158:                 if (compareAndSetState(c, nextc))
 159:                     return nextc == 0;
 160:             }
 161:         }
 162:     }
 163: 
 164:     private final Sync sync;
 165: 
 166:     /**
 167:      * Constructs a {@code CountDownLatch} initialized with the given count.
 168:      *
 169:      * @param count the number of times {@link #countDown} must be invoked
 170:      *        before threads can pass through {@link #await}
 171:      * @throws IllegalArgumentException if {@code count} is negative
 172:      */
 173:     public CountDownLatch(int count) {
 174:         if (count < 0) throw new IllegalArgumentException("count < 0");
 175:         this.sync = new Sync(count);
 176:     }
 177: 
 178:     /**
 179:      * Causes the current thread to wait until the latch has counted down to
 180:      * zero, unless the thread is {@linkplain Thread#interrupt interrupted}.
 181:      *
 182:      * <p>If the current count is zero then this method returns immediately.
 183:      *
 184:      * <p>If the current count is greater than zero then the current
 185:      * thread becomes disabled for thread scheduling purposes and lies
 186:      * dormant until one of two things happen:
 187:      * <ul>
 188:      * <li>The count reaches zero due to invocations of the
 189:      * {@link #countDown} method; or
 190:      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
 191:      * the current thread.
 192:      * </ul>
 193:      *
 194:      * <p>If the current thread:
 195:      * <ul>
 196:      * <li>has its interrupted status set on entry to this method; or
 197:      * <li>is {@linkplain Thread#interrupt interrupted} while waiting,
 198:      * </ul>
 199:      * then {@link InterruptedException} is thrown and the current thread's
 200:      * interrupted status is cleared.
 201:      *
 202:      * @throws InterruptedException if the current thread is interrupted
 203:      *         while waiting
 204:      */
 205:     public void await() throws InterruptedException {
 206:         sync.acquireSharedInterruptibly(1);
 207:     }
 208: 
 209:     /**
 210:      * Causes the current thread to wait until the latch has counted down to
 211:      * zero, unless the thread is {@linkplain Thread#interrupt interrupted},
 212:      * or the specified waiting time elapses.
 213:      *
 214:      * <p>If the current count is zero then this method returns immediately
 215:      * with the value {@code true}.
 216:      *
 217:      * <p>If the current count is greater than zero then the current
 218:      * thread becomes disabled for thread scheduling purposes and lies
 219:      * dormant until one of three things happen:
 220:      * <ul>
 221:      * <li>The count reaches zero due to invocations of the
 222:      * {@link #countDown} method; or
 223:      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
 224:      * the current thread; or
 225:      * <li>The specified waiting time elapses.
 226:      * </ul>
 227:      *
 228:      * <p>If the count reaches zero then the method returns with the
 229:      * value {@code true}.
 230:      *
 231:      * <p>If the current thread:
 232:      * <ul>
 233:      * <li>has its interrupted status set on entry to this method; or
 234:      * <li>is {@linkplain Thread#interrupt interrupted} while waiting,
 235:      * </ul>
 236:      * then {@link InterruptedException} is thrown and the current thread's
 237:      * interrupted status is cleared.
 238:      *
 239:      * <p>If the specified waiting time elapses then the value {@code false}
 240:      * is returned.  If the time is less than or equal to zero, the method
 241:      * will not wait at all.
 242:      *
 243:      * @param timeout the maximum time to wait
 244:      * @param unit the time unit of the {@code timeout} argument
 245:      * @return {@code true} if the count reached zero and {@code false}
 246:      *         if the waiting time elapsed before the count reached zero
 247:      * @throws InterruptedException if the current thread is interrupted
 248:      *         while waiting
 249:      */
 250:     public boolean await(long timeout, TimeUnit unit)
 251:         throws InterruptedException {
 252:         return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
 253:     }
 254: 
 255:     /**
 256:      * Decrements the count of the latch, releasing all waiting threads if
 257:      * the count reaches zero.
 258:      *
 259:      * <p>If the current count is greater than zero then it is decremented.
 260:      * If the new count is zero then all waiting threads are re-enabled for
 261:      * thread scheduling purposes.
 262:      *
 263:      * <p>If the current count equals zero then nothing happens.
 264:      */
 265:     public void countDown() {
 266:         sync.releaseShared(1);
 267:     }
 268: 
 269:     /**
 270:      * Returns the current count.
 271:      *
 272:      * <p>This method is typically used for debugging and testing purposes.
 273:      *
 274:      * @return the current count
 275:      */
 276:     public long getCount() {
 277:         return sync.getCount();
 278:     }
 279: 
 280:     /**
 281:      * Returns a string identifying this latch, as well as its state.
 282:      * The state, in brackets, includes the String {@code "Count ="}
 283:      * followed by the current count.
 284:      *
 285:      * @return a string identifying this latch, as well as its state
 286:      */
 287:     public String toString() {
 288:         return super.toString() + "[Count = " + sync.getCount() + "]";
 289:     }
 290: }