1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/CountDownLatch.java Sat Mar 19 10:46:31 2016 +0100
1.3 @@ -0,0 +1,320 @@
1.4 +/*
1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.6 + *
1.7 + * This code is free software; you can redistribute it and/or modify it
1.8 + * under the terms of the GNU General Public License version 2 only, as
1.9 + * published by the Free Software Foundation. Oracle designates this
1.10 + * particular file as subject to the "Classpath" exception as provided
1.11 + * by Oracle in the LICENSE file that accompanied this code.
1.12 + *
1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.16 + * version 2 for more details (a copy is included in the LICENSE file that
1.17 + * accompanied this code).
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License version
1.20 + * 2 along with this work; if not, write to the Free Software Foundation,
1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.22 + *
1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.24 + * or visit www.oracle.com if you need additional information or have any
1.25 + * questions.
1.26 + */
1.27 +
1.28 +/*
1.29 + * This file is available under and governed by the GNU General Public
1.30 + * License version 2 only, as published by the Free Software Foundation.
1.31 + * However, the following notice accompanied the original version of this
1.32 + * file:
1.33 + *
1.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
1.35 + * Expert Group and released to the public domain, as explained at
1.36 + * http://creativecommons.org/publicdomain/zero/1.0/
1.37 + */
1.38 +
1.39 +package java.util.concurrent;
1.40 +import java.util.concurrent.locks.*;
1.41 +import java.util.concurrent.atomic.*;
1.42 +
1.43 +/**
1.44 + * A synchronization aid that allows one or more threads to wait until
1.45 + * a set of operations being performed in other threads completes.
1.46 + *
1.47 + * <p>A {@code CountDownLatch} is initialized with a given <em>count</em>.
1.48 + * The {@link #await await} methods block until the current count reaches
1.49 + * zero due to invocations of the {@link #countDown} method, after which
1.50 + * all waiting threads are released and any subsequent invocations of
1.51 + * {@link #await await} return immediately. This is a one-shot phenomenon
1.52 + * -- the count cannot be reset. If you need a version that resets the
1.53 + * count, consider using a {@link CyclicBarrier}.
1.54 + *
1.55 + * <p>A {@code CountDownLatch} is a versatile synchronization tool
1.56 + * and can be used for a number of purposes. A
1.57 + * {@code CountDownLatch} initialized with a count of one serves as a
1.58 + * simple on/off latch, or gate: all threads invoking {@link #await await}
1.59 + * wait at the gate until it is opened by a thread invoking {@link
1.60 + * #countDown}. A {@code CountDownLatch} initialized to <em>N</em>
1.61 + * can be used to make one thread wait until <em>N</em> threads have
1.62 + * completed some action, or some action has been completed N times.
1.63 + *
1.64 + * <p>A useful property of a {@code CountDownLatch} is that it
1.65 + * doesn't require that threads calling {@code countDown} wait for
1.66 + * the count to reach zero before proceeding, it simply prevents any
1.67 + * thread from proceeding past an {@link #await await} until all
1.68 + * threads could pass.
1.69 + *
1.70 + * <p><b>Sample usage:</b> Here is a pair of classes in which a group
1.71 + * of worker threads use two countdown latches:
1.72 + * <ul>
1.73 + * <li>The first is a start signal that prevents any worker from proceeding
1.74 + * until the driver is ready for them to proceed;
1.75 + * <li>The second is a completion signal that allows the driver to wait
1.76 + * until all workers have completed.
1.77 + * </ul>
1.78 + *
1.79 + * <pre>
1.80 + * class Driver { // ...
1.81 + * void main() throws InterruptedException {
1.82 + * CountDownLatch startSignal = new CountDownLatch(1);
1.83 + * CountDownLatch doneSignal = new CountDownLatch(N);
1.84 + *
1.85 + * for (int i = 0; i < N; ++i) // create and start threads
1.86 + * new Thread(new Worker(startSignal, doneSignal)).start();
1.87 + *
1.88 + * doSomethingElse(); // don't let run yet
1.89 + * startSignal.countDown(); // let all threads proceed
1.90 + * doSomethingElse();
1.91 + * doneSignal.await(); // wait for all to finish
1.92 + * }
1.93 + * }
1.94 + *
1.95 + * class Worker implements Runnable {
1.96 + * private final CountDownLatch startSignal;
1.97 + * private final CountDownLatch doneSignal;
1.98 + * Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
1.99 + * this.startSignal = startSignal;
1.100 + * this.doneSignal = doneSignal;
1.101 + * }
1.102 + * public void run() {
1.103 + * try {
1.104 + * startSignal.await();
1.105 + * doWork();
1.106 + * doneSignal.countDown();
1.107 + * } catch (InterruptedException ex) {} // return;
1.108 + * }
1.109 + *
1.110 + * void doWork() { ... }
1.111 + * }
1.112 + *
1.113 + * </pre>
1.114 + *
1.115 + * <p>Another typical usage would be to divide a problem into N parts,
1.116 + * describe each part with a Runnable that executes that portion and
1.117 + * counts down on the latch, and queue all the Runnables to an
1.118 + * Executor. When all sub-parts are complete, the coordinating thread
1.119 + * will be able to pass through await. (When threads must repeatedly
1.120 + * count down in this way, instead use a {@link CyclicBarrier}.)
1.121 + *
1.122 + * <pre>
1.123 + * class Driver2 { // ...
1.124 + * void main() throws InterruptedException {
1.125 + * CountDownLatch doneSignal = new CountDownLatch(N);
1.126 + * Executor e = ...
1.127 + *
1.128 + * for (int i = 0; i < N; ++i) // create and start threads
1.129 + * e.execute(new WorkerRunnable(doneSignal, i));
1.130 + *
1.131 + * doneSignal.await(); // wait for all to finish
1.132 + * }
1.133 + * }
1.134 + *
1.135 + * class WorkerRunnable implements Runnable {
1.136 + * private final CountDownLatch doneSignal;
1.137 + * private final int i;
1.138 + * WorkerRunnable(CountDownLatch doneSignal, int i) {
1.139 + * this.doneSignal = doneSignal;
1.140 + * this.i = i;
1.141 + * }
1.142 + * public void run() {
1.143 + * try {
1.144 + * doWork(i);
1.145 + * doneSignal.countDown();
1.146 + * } catch (InterruptedException ex) {} // return;
1.147 + * }
1.148 + *
1.149 + * void doWork() { ... }
1.150 + * }
1.151 + *
1.152 + * </pre>
1.153 + *
1.154 + * <p>Memory consistency effects: Until the count reaches
1.155 + * zero, actions in a thread prior to calling
1.156 + * {@code countDown()}
1.157 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
1.158 + * actions following a successful return from a corresponding
1.159 + * {@code await()} in another thread.
1.160 + *
1.161 + * @since 1.5
1.162 + * @author Doug Lea
1.163 + */
1.164 +public class CountDownLatch {
1.165 + /**
1.166 + * Synchronization control For CountDownLatch.
1.167 + * Uses AQS state to represent count.
1.168 + */
1.169 + private static final class Sync extends AbstractQueuedSynchronizer {
1.170 + private static final long serialVersionUID = 4982264981922014374L;
1.171 +
1.172 + Sync(int count) {
1.173 + setState(count);
1.174 + }
1.175 +
1.176 + int getCount() {
1.177 + return getState();
1.178 + }
1.179 +
1.180 + protected int tryAcquireShared(int acquires) {
1.181 + return (getState() == 0) ? 1 : -1;
1.182 + }
1.183 +
1.184 + protected boolean tryReleaseShared(int releases) {
1.185 + // Decrement count; signal when transition to zero
1.186 + for (;;) {
1.187 + int c = getState();
1.188 + if (c == 0)
1.189 + return false;
1.190 + int nextc = c-1;
1.191 + if (compareAndSetState(c, nextc))
1.192 + return nextc == 0;
1.193 + }
1.194 + }
1.195 + }
1.196 +
1.197 + private final Sync sync;
1.198 +
1.199 + /**
1.200 + * Constructs a {@code CountDownLatch} initialized with the given count.
1.201 + *
1.202 + * @param count the number of times {@link #countDown} must be invoked
1.203 + * before threads can pass through {@link #await}
1.204 + * @throws IllegalArgumentException if {@code count} is negative
1.205 + */
1.206 + public CountDownLatch(int count) {
1.207 + if (count < 0) throw new IllegalArgumentException("count < 0");
1.208 + this.sync = new Sync(count);
1.209 + }
1.210 +
1.211 + /**
1.212 + * Causes the current thread to wait until the latch has counted down to
1.213 + * zero, unless the thread is {@linkplain Thread#interrupt interrupted}.
1.214 + *
1.215 + * <p>If the current count is zero then this method returns immediately.
1.216 + *
1.217 + * <p>If the current count is greater than zero then the current
1.218 + * thread becomes disabled for thread scheduling purposes and lies
1.219 + * dormant until one of two things happen:
1.220 + * <ul>
1.221 + * <li>The count reaches zero due to invocations of the
1.222 + * {@link #countDown} method; or
1.223 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
1.224 + * the current thread.
1.225 + * </ul>
1.226 + *
1.227 + * <p>If the current thread:
1.228 + * <ul>
1.229 + * <li>has its interrupted status set on entry to this method; or
1.230 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting,
1.231 + * </ul>
1.232 + * then {@link InterruptedException} is thrown and the current thread's
1.233 + * interrupted status is cleared.
1.234 + *
1.235 + * @throws InterruptedException if the current thread is interrupted
1.236 + * while waiting
1.237 + */
1.238 + public void await() throws InterruptedException {
1.239 + sync.acquireSharedInterruptibly(1);
1.240 + }
1.241 +
1.242 + /**
1.243 + * Causes the current thread to wait until the latch has counted down to
1.244 + * zero, unless the thread is {@linkplain Thread#interrupt interrupted},
1.245 + * or the specified waiting time elapses.
1.246 + *
1.247 + * <p>If the current count is zero then this method returns immediately
1.248 + * with the value {@code true}.
1.249 + *
1.250 + * <p>If the current count is greater than zero then the current
1.251 + * thread becomes disabled for thread scheduling purposes and lies
1.252 + * dormant until one of three things happen:
1.253 + * <ul>
1.254 + * <li>The count reaches zero due to invocations of the
1.255 + * {@link #countDown} method; or
1.256 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
1.257 + * the current thread; or
1.258 + * <li>The specified waiting time elapses.
1.259 + * </ul>
1.260 + *
1.261 + * <p>If the count reaches zero then the method returns with the
1.262 + * value {@code true}.
1.263 + *
1.264 + * <p>If the current thread:
1.265 + * <ul>
1.266 + * <li>has its interrupted status set on entry to this method; or
1.267 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting,
1.268 + * </ul>
1.269 + * then {@link InterruptedException} is thrown and the current thread's
1.270 + * interrupted status is cleared.
1.271 + *
1.272 + * <p>If the specified waiting time elapses then the value {@code false}
1.273 + * is returned. If the time is less than or equal to zero, the method
1.274 + * will not wait at all.
1.275 + *
1.276 + * @param timeout the maximum time to wait
1.277 + * @param unit the time unit of the {@code timeout} argument
1.278 + * @return {@code true} if the count reached zero and {@code false}
1.279 + * if the waiting time elapsed before the count reached zero
1.280 + * @throws InterruptedException if the current thread is interrupted
1.281 + * while waiting
1.282 + */
1.283 + public boolean await(long timeout, TimeUnit unit)
1.284 + throws InterruptedException {
1.285 + return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
1.286 + }
1.287 +
1.288 + /**
1.289 + * Decrements the count of the latch, releasing all waiting threads if
1.290 + * the count reaches zero.
1.291 + *
1.292 + * <p>If the current count is greater than zero then it is decremented.
1.293 + * If the new count is zero then all waiting threads are re-enabled for
1.294 + * thread scheduling purposes.
1.295 + *
1.296 + * <p>If the current count equals zero then nothing happens.
1.297 + */
1.298 + public void countDown() {
1.299 + sync.releaseShared(1);
1.300 + }
1.301 +
1.302 + /**
1.303 + * Returns the current count.
1.304 + *
1.305 + * <p>This method is typically used for debugging and testing purposes.
1.306 + *
1.307 + * @return the current count
1.308 + */
1.309 + public long getCount() {
1.310 + return sync.getCount();
1.311 + }
1.312 +
1.313 + /**
1.314 + * Returns a string identifying this latch, as well as its state.
1.315 + * The state, in brackets, includes the String {@code "Count ="}
1.316 + * followed by the current count.
1.317 + *
1.318 + * @return a string identifying this latch, as well as its state
1.319 + */
1.320 + public String toString() {
1.321 + return super.toString() + "[Count = " + sync.getCount() + "]";
1.322 + }
1.323 +}