|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CountDownLatch | Line # 131 | 30 | 17 | 87.5% |
0.875
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (9) | |||
| Result | |||
|
0.5
|
CountDownLatchTest.testTimedAwait
CountDownLatchTest.testTimedAwait
|
1 PASS | |
|
0.42857143
|
CountDownLatchTest.testAwaitTimeout
CountDownLatchTest.testAwaitTimeout
|
1 PASS | |
|
0.375
|
CountDownLatchTest.testAwait
CountDownLatchTest.testAwait
|
1 PASS | |
|
0.32142857
|
CountDownLatchTest.testTimedAwait_InterruptedException
CountDownLatchTest.testTimedAwait_InterruptedException
|
1 PASS | |
|
0.26785713
|
CountDownLatchTest.testToString
CountDownLatchTest.testToString
|
1 PASS | |
|
0.25
|
CountDownLatchTest.testCountDown
CountDownLatchTest.testCountDown
|
1 PASS | |
|
0.19642857
|
CountDownLatchTest.testGetCount
CountDownLatchTest.testGetCount
|
1 PASS | |
|
0.17857143
|
CountDownLatchTest.testAwait_InterruptedException
CountDownLatchTest.testAwait_InterruptedException
|
1 PASS | |
|
0.071428575
|
CountDownLatchTest.testConstructor
CountDownLatchTest.testConstructor
|
1 PASS | |
| 1 | /* | |
| 2 | * Written by Doug Lea with assistance from members of JCP JSR-166 | |
| 3 | * Expert Group and released to the public domain. Use, modify, and | |
| 4 | * redistribute this code in any way without acknowledgement. | |
| 5 | */ | |
| 6 | ||
| 7 | package edu.emory.mathcs.backport.java.util.concurrent; | |
| 8 | ||
| 9 | import edu.emory.mathcs.backport.java.util.concurrent.helpers.*; | |
| 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 | private int count_; | |
| 134 | ||
| 135 | /** | |
| 136 | * Constructs a {@code CountDownLatch} initialized with the given count. | |
| 137 | * | |
| 138 | * @param count the number of times {@link #countDown} must be invoked | |
| 139 | * before threads can pass through {@link #await} | |
| 140 | * @throws IllegalArgumentException if {@code count} is negative | |
| 141 | */ | |
| 142 | 9 |
public CountDownLatch(int count) { |
| 143 | 9 | if (count < 0) throw new IllegalArgumentException("count < 0"); |
| 144 | 8 | this.count_ = count; |
| 145 | } | |
| 146 | ||
| 147 | /** | |
| 148 | * Causes the current thread to wait until the latch has counted down to | |
| 149 | * zero, unless the thread is {@linkplain Thread#interrupt interrupted}. | |
| 150 | * | |
| 151 | * <p>If the current count is zero then this method returns immediately. | |
| 152 | * | |
| 153 | * <p>If the current count is greater than zero then the current | |
| 154 | * thread becomes disabled for thread scheduling purposes and lies | |
| 155 | * dormant until one of two things happen: | |
| 156 | * <ul> | |
| 157 | * <li>The count reaches zero due to invocations of the | |
| 158 | * {@link #countDown} method; or | |
| 159 | * <li>Some other thread {@linkplain Thread#interrupt interrupts} | |
| 160 | * the current thread. | |
| 161 | * </ul> | |
| 162 | * | |
| 163 | * <p>If the current thread: | |
| 164 | * <ul> | |
| 165 | * <li>has its interrupted status set on entry to this method; or | |
| 166 | * <li>is {@linkplain Thread#interrupt interrupted} while waiting, | |
| 167 | * </ul> | |
| 168 | * then {@link InterruptedException} is thrown and the current thread's | |
| 169 | * interrupted status is cleared. | |
| 170 | * | |
| 171 | * @throws InterruptedException if the current thread is interrupted | |
| 172 | * while waiting | |
| 173 | */ | |
| 174 | 2 |
public void await() throws InterruptedException { |
| 175 | 2 | if (Thread.interrupted()) throw new InterruptedException(); |
| 176 | 1 | synchronized(this) { |
| 177 | 2 | while (count_ > 0) |
| 178 | 1 | wait(); |
| 179 | } | |
| 180 | } | |
| 181 | ||
| 182 | /** | |
| 183 | * Causes the current thread to wait until the latch has counted down to | |
| 184 | * zero, unless the thread is {@linkplain Thread#interrupt interrupted}, | |
| 185 | * or the specified waiting time elapses. | |
| 186 | * | |
| 187 | * <p>If the current count is zero then this method returns immediately | |
| 188 | * with the value {@code true}. | |
| 189 | * | |
| 190 | * <p>If the current count is greater than zero then the current | |
| 191 | * thread becomes disabled for thread scheduling purposes and lies | |
| 192 | * dormant until one of three things happen: | |
| 193 | * <ul> | |
| 194 | * <li>The count reaches zero due to invocations of the | |
| 195 | * {@link #countDown} method; or | |
| 196 | * <li>Some other thread {@linkplain Thread#interrupt interrupts} | |
| 197 | * the current thread; or | |
| 198 | * <li>The specified waiting time elapses. | |
| 199 | * </ul> | |
| 200 | * | |
| 201 | * <p>If the count reaches zero then the method returns with the | |
| 202 | * value {@code true}. | |
| 203 | * | |
| 204 | * <p>If the current thread: | |
| 205 | * <ul> | |
| 206 | * <li>has its interrupted status set on entry to this method; or | |
| 207 | * <li>is {@linkplain Thread#interrupt interrupted} while waiting, | |
| 208 | * </ul> | |
| 209 | * then {@link InterruptedException} is thrown and the current thread's | |
| 210 | * interrupted status is cleared. | |
| 211 | * | |
| 212 | * <p>If the specified waiting time elapses then the value {@code false} | |
| 213 | * is returned. If the time is less than or equal to zero, the method | |
| 214 | ||