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:终于可以吃饭啦!