1,一个例子

/**
 * CyclicBarrier维持一个计数器,与CountDownLatch不同的是,等待这个CyclicBarrier的线程必须等到计数器
 * 的某个值时,才可以继续.
 * CyclicBarrier就像它名字的意思一样,可看成是个障碍,所有的线程必须到齐后才能一起通过这个障碍.
 */
/**
 * 本实例实现一个数组相邻元素的加法,一个线程给数组的第一个元素赋值,然后等待其它线程给数组第二个元素赋值,
 * 然后将第一个元素和第二个元素相加.
 */
/**
 * CyclicBarrier的关键技术点如下:
 * 1.构造CyclicBarrier对象时,需要指定计数器的目标值,计数器的初始值为0.
 * 还可以在构造方法中带一个 Runnable参数,表示当计数器到达目标值是,在等待CyclicBarrier的线程被唤醒之前,
 * 指定该Runnable任务.
 * 2.CyclicBarrier的await方法使当前线程进入等待状态,同时将计数器值加1,当计数器到达目标值时,当前线程被唤醒.
 */
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{
				//Random的nextInt(int n)方法返回一个[0,n)范围内的随机数
				array[ID] = new Random().nextInt(100);
				System.out.println("Componet " + ID + " sleep...");
				barrier.await();
				System.out.println("Componet " + ID + " awaked...");
				//计算数据数组中的当前值和后续值
				int result = array[ID] + array[ID + 1];
				System.out.println("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(){
			public void run(){
				System.out.println("testCyclicBarrier run...");
				array[2] = array[0] + array[1];
				System.out.println("Result: "+array[2]);
			}
		});
		//启动线程
		new Thread(new ComponentThread(barrier,array,0)).start();
		new Thread(new ComponentThread(barrier,array,1)).start();
	}

	public static void main(String... args){
		CyclicBarrierTest.testCyclicBarrier();
	}
}

 


结果 写道


Componet 0 sleep...
Componet 1 sleep...
testCyclicBarrier run...
Result: 173
Componet 1 awaked...
Component 1 result: 253
Componet 0 awaked...
Component 0 result: 173


 

注意:CyclicBarrier 到达计数后先执行自己的Runnable的方法。如,上面的结果先打印出testCyclicBarrier run... 后awake其他的线程。

 

2,又一个例子


public class CyclicBarrierTest {
    public static void main(String[] args) throws InterruptedException {   
        ExecutorService exec = Executors.newCachedThreadPool();        
        final CyclicBarrier barrier = new CyclicBarrier(4, new Runnable() {   
            public void run() {   
                System.out.println("好了,大家可以去吃饭了……"  );   
            }   
        });
        System.out.println("要吃饭,必须所有人都到终点,oK?");                   
        System.out.println("不放弃不抛弃!");   
        for (int i = 0; i < 4; i++) {
            exec.execute(new Runnable() {   
                public void run() {   
                    System.out.println(Thread.currentThread().getName() + ":Go");   
                    try {   
                        Thread.sleep((long) (2000 * Math.random()));   
                    } catch (InterruptedException e1) {   
                        e1.printStackTrace();   
                    }   
                    System.out.println(Thread.currentThread().getName()+ ":我到终点了");   
                    try {   
                        barrier.await();   
                    } catch (InterruptedException e) {   
                        e.printStackTrace();   
                    } catch (BrokenBarrierException e) {   
                        e.printStackTrace();   
                    }   
                    System.out.println(Thread.currentThread().getName()   
                            + ":终于可以吃饭啦!");   
                }   
            });   
        }
        exec.shutdown();   
    }
}

 


结果 写道


要吃饭,必须所有人都到终点,oK?
不放弃不抛弃!
pool-1-thread-1:Go
pool-1-thread-3:Go
pool-1-thread-2:Go
pool-1-thread-4:Go
pool-1-thread-2:我到终点了
pool-1-thread-4:我到终点了
pool-1-thread-1:我到终点了
pool-1-thread-3:我到终点了
好了,大家可以去吃饭了……
pool-1-thread-2:终于可以吃饭啦!
pool-1-thread-4:终于可以吃饭啦!
pool-1-thread-1:终于可以吃饭啦!
pool-1-thread-3:终于可以吃饭啦!