Clover Coverage Report - Backport Util Concurrent v3.0
Coverage timestamp: Fri May 9 2008 11:05:23 EST
../../../../../../../img/srcFileCovDistChart9.png 35% of files have more coverage
30   284   17   5
20   50   0.57   6
6     2.83  
1    
 
  CountDownLatch       Line # 131 30 17 87.5% 0.875
 
  (9)
 
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 toggle 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 toggle 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