A CyclicBarrier supports an optional Runnable command that is run once per barrier point, after the last thread in the party arrives, but before any threads are released. This barrier action is useful for updating shared-state before any of the parties continue.
The CountDownLatch class is useful for various types of "one-off" thread coordination, in particular setting threads off together. However, it has at least two features that can be inconvenient in certain situations:
* a given CountDownLatch can only be used once, making it inconvenient for operations that occur in stages, with intermediate results from the different threads needing to be amalgamated between stages;
* the CountDownLatch doesn't explicitly allow one thread to tell the others to "stop waiting"1, which is sometimes useful, for example, if an error occurs in one of the threads.
The CyclicBarrier is generally more useful than CountDownLatch in cases where:
* a multithreaded operation occurs in stages or iterations, and;
* a single-threaded operation is required between stages/iterations, for example, to combine the results of the previous multithreaded portion.
package thread.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class TestCyclicBarrier {
class Worker extends Thread {
CyclicBarrier barrier;
// name of the thread
String name;
public Worker(String threadName, CyclicBarrier cBarrier) {
barrier = cBarrier;
name = threadName;
}
public void run() {
System.out.println("WAITING says:" + name);
try {
barrier.await();
System.out.println("WORKING HARD NOW says:"+ name);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("FINISHED says: "+ name);
}
}
public void testCyclicBarrier() {
CyclicBarrier barrier = new CyclicBarrier(2, new Runnable() {
public void run() {
try {
System.out.println("START Barrier Action ....");
Thread.sleep(1000);
System.out.println("STOP Barrier Action ....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
for (int i = 0; i < 2; i++) {
Worker worker = new Worker("Thread_"+i,barrier);
worker.start();
}
}
public static void main(String[] args) {
TestCyclicBarrier t = new TestCyclicBarrier();
t.testCyclicBarrier();
}
}
Output
WAITING says:Thread_0 WAITING says:Thread_1 START Barrier Action .... STOP Barrier Action .... WORKING HARD NOW says:Thread_0 WORKING HARD NOW says:Thread_1 FINISHED says: Thread_1 FINISHED says: Thread_0 Process exited with exit code 0.
No comments:
Post a Comment