CountdownLatch
class is similar to CyclicBarrier
, in that its role
is to coordinate a group of threads that have divided a problem
among themselves. It is also constructed with an integer argument,
indicating the initial value of the count, but, unlike CyclicBarrier
, is
not reusable.
Where
CyclicBarrier
acts as a gate to all the threads
that reach the barrier, allowing them through only when all the
threads have arrived at the barrier or the barrier is broken,
CountdownLatch
separates the arrival and waiting
functionality. Any thread can decrement the current count by calling
countDown()
, which does not block, but merely decrements
the count. The await() method behaves slightly differently than
CyclicBarrier.await()
-- any threads that call
await()
will block until the latch count gets down to
zero, at which point all threads waiting will be released, and
subsequent calls to await()
will return immediately.
CountdownLatch
is useful when a problem has been
decomposed into a number of pieces, and each thread has been given a
piece of the computation. When the worker threads finish, they
decrement the count, and the coordination thread(s) can wait on the
latch for the current batch of computations to finish before moving on
to the next batch.
Conversely, a
CountdownLatch
class with a count of 1 can be
used as a "starting gate" to start a group of threads at once; the
worker threads wait on the latch, and the coordinating thread
decrements the count, which releases all the worker threads at once.
The following example uses two CountdownLatche
s; ones as a starting
gate, and one that releases when all the worker threads are
finished:
class Driver { // ... void main() throws InterruptedException { CountDownLatch startSignal = new CountDownLatch(1); CountDownLatch doneSignal = new CountDownLatch(N); for (int i = 0; i < N; ++i) // create and start threads new Thread(new Worker(startSignal, doneSignal)).start(); doSomethingElse(); // don't let them run yet startSignal.countDown(); // let all threads proceed doSomethingElse(); doneSignal.await(); // wait for all to finish } } class Worker implements Runnable { private final CountDownLatch startSignal; private final CountDownLatch doneSignal; Worker(CountDownLatch startSignal, CountDownLatch doneSignal) { this.startSignal = startSignal; this.doneSignal = doneSignal; } public void run() { try { startSignal.await(); doWork(); doneSignal.countDown(); } catch (InterruptedException ex) {} // return; } }
Kindly provide your valuable feedback in comment box.
No comments:
Post a Comment