CyclicBarrier在java.util.concurrent包下,是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。CyclicBarrier 支持一个可选的 Runnable
命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。
构造方法
public CyclicBarrier(int parties)创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在启动 barrier 时执行预定义的操作。
参数:parties - 在启动 barrier 前必须调用 await() 的线程数
抛出:IllegalArgumentException - 如果 parties 小于 1
public CyclicBarrier(int parties,
Runnable barrierAction)创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。
参数:parties - 在启动 barrier 前必须调用 await() 的线程数
barrierAction - 在启动 barrier 时执行的命令;如果不执行任何操作,则该参数为 null
抛出:IllegalArgumentException - 如果 parties 小于 1
方法摘要
int await()
在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
int await(long timeout, TimeUnit unit)
在所有参与者都已经在此屏障上调用 await 方法之前将一直等待,或者超出了指定的等待时间。
int getNumberWaiting()
返回当前在屏障处等待的参与者数目。
int getParties()
返回要求启动此 barrier 的参与者数目。
boolean isBroken()
查询此屏障是否处于损坏状态。
void reset()
将屏障重置为其初始状态。
如下代码演示赛跑,等到barrier上所有线程都调用await方法后才往下执行:
/**
* Huisou.com Inc.
* Copyright (c) 2011-2012 All Rights Reserved.
*/
package thread;
import java.io.IOException;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* @description
*
* @author chenzehe
* @email hljuczh@163.com
* @create 2013-1-11 下午03:04:06
*/
public class CyclicBarrierTest {
public static void main(String[] args) throws IOException, InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(3);
new Thread(new Runner(barrier, "1号选手")).start();
new Thread(new Runner(barrier, "2号选手")).start();
new Thread(new Runner(barrier, "3号选手")).start();
}
}
class Runner implements Runnable {
private CyclicBarrier barrier;
private String name;
public Runner(CyclicBarrier barrier, String name) {
super();
this.barrier = barrier;
this.name = name;
}
@Override
public void run() {
try {
Thread.sleep(3000);
System.out.println(name + " 准备好了...");
// barrier的await方法,在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
barrier.await();
System.out.println(name + " 起跑!");
}
catch (InterruptedException e) {
e.printStackTrace();
}
catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
1号选手 准备好了...
3号选手 准备好了...
2号选手 准备好了...
1号选手 起跑!
3号选手 起跑!
2号选手 起跑!