CyclicBarrier
字面意思回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行。叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier可以被重用。我们暂且把这个状态就叫做barrier,当调用await()方法之后,线程就处于barrier了。
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。
在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。
因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。
若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。
主要方法:
//设置barties(障点对象)、count(等待的线程数)及barrierCommand(Runnable)属性。
public CountDownLatch(int count) { }; //参数count为计数值
public void await() throws InterruptedException { }; //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { }; //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public void countDown() { }; //将count值减1
//当await的数量到达了设定的数量后,首先执行该Runnable对象。
CyclicBarrier(int,Runnable):
//通知barrier已完成线程
await(): //让当前线程处理wait状态
package thread.cyclic; import java.util.Random; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.TimeUnit; /** * CyclicBarrier类似于CountDownLatch也是个计数器, * 不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数, * 当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。 * CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 * CyclicBarrier初始时还可带一个Runnable的参数, * 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。 */ public class CyclicBarrierTest { public static class ComponentThread implements Runnable { CyclicBarrier barrier;// 计数器 int ID; // 组件标识 int[] array; // 数据数组 // 构造方法 public ComponentThread(CyclicBarrier barrier, int[] array, int ID) { this.barrier = barrier; this.ID = ID; this.array = array; } public void run() { try { array[ID] = new Random().nextInt(100); System.out.println(Thread.currentThread() + "Component " + ID + " generates: " + array[ID]); // 在这里等待Barrier处 TimeUnit.SECONDS.sleep(1); System.out.println(Thread.currentThread() + "Component " + ID + " sleep..."); barrier.await(); System.out.println(Thread.currentThread() + "Component " + ID + " awaked..."); // 计算数据数组中的当前值和后续值 int result = array[ID] + array[ID + 1]; System.out.println(Thread.currentThread() + "Component " + ID + " result: " + result); } catch (Exception ex) { } } } /** * 测试CyclicBarrier的用法 */ public static void testCyclicBarrier() { final int[] array = new int[3]; CyclicBarrier barrier = new CyclicBarrier(2, new Runnable() { // 在所有线程都到达Barrier时执行 public void run() { System.out.println(Thread.currentThread() + "testCyclicBarrier run..."); array[2] = array[0] + array[1]; } }); // 启动线程 new Thread(new ComponentThread(barrier, array, 0)).start(); new Thread(new ComponentThread(barrier, array, 1)).start(); } public static void main(String[] args) { CyclicBarrierTest.testCyclicBarrier(); } }
Output:
Thread[Thread-0,5,main]Component 0 generates: 32 Thread[Thread-1,5,main]Component 1 generates: 41 Thread[Thread-1,5,main]Component 1 sleep... Thread[Thread-0,5,main]Component 0 sleep... Thread[Thread-0,5,main]testCyclicBarrier run... Thread[Thread-0,5,main]Component 0 awaked... Thread[Thread-0,5,main]Component 0 result: 73 Thread[Thread-1,5,main]Component 1 awaked... Thread[Thread-1,5,main]Component 1 result: 114
or:
Thread[Thread-0,5,main]Component 0 generates: 33 Thread[Thread-1,5,main]Component 1 generates: 50 Thread[Thread-0,5,main]Component 0 sleep... Thread[Thread-1,5,main]Component 1 sleep... Thread[Thread-1,5,main]testCyclicBarrier run... Thread[Thread-0,5,main]Component 0 awaked... Thread[Thread-0,5,main]Component 0 result: 83 Thread[Thread-1,5,main]Component 1 awaked... Thread[Thread-1,5,main]Component 1 result: 133
http://blog.csdn.net/huang_xw/article/details/7090152