一、什么叫CyclicBarrier?
1.字面意思:可循环使用的屏障。
2.主要做的事情:让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障;屏障才会开门,所有被屏障拦截的线程才会继续进行。
二、CyclicBarrier类API
构造器
CyclicBarrier(int parties) 创建CyclicBarrier对象,parties 表示屏障拦截的线程数量。
CyclicBarrier(int parties, Runnable barrierAction) 创建 CyclicBarrier对象,该构造方法提供了一个Runnable 参数,在一组线程中的最后一个线程到达之后,执行Runnable中的程序,再之后释放正在等待的线程。Runnable在屏障点上只运行一次。
方法
int await() 通知CyclicBarrier实例,当前线程已经到达屏障点,然后当前线程将被阻塞。
int await(long timeout, TimeUnit unit) 指定当前线程被阻塞的时间。
int getNumberWaiting() 返回当前在屏障处等待的线程数。
int getParties() 返回CyclicBarrier的需要拦截的线程数。
boolean isBroken() 查询此屏障是否处于损坏状态。
void reset() 将屏障重置为其初始状态。
三
public class TestCyclicBarrier {
private static final int THREAD_NUM = 5;
public static class WorkerThread implements Runnable{
CyclicBarrier barrier;
public WorkerThread(CyclicBarrier b){
this.barrier = b;
}
@Override
public void run() {
// TODO Auto-generated method stub
try{
System.out.println("Worker's waiting");
//线程在这里等待,直到所有线程都到达barrier。
barrier.await();
System.out.println("ID:"+Thread.currentThread().getId()+" Working");
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
CyclicBarrier cb = new CyclicBarrier(THREAD_NUM, new Runnable() {
//当所有线程到达barrier时执行
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Inside Barrier");
}
});
for(int i=0;i<THREAD_NUM;i++){
new Thread(new WorkerThread(cb)).start();
}
}
}
/*
以下是输出:
Worker’s waiting
Worker’s waiting
Worker’s waiting
Worker’s waiting
Worker’s waiting
Inside Barrier
ID:12 Working
ID:8 Working
ID:11 Working
ID:9 Working
ID:10 Working
*/
CyclicBarrier初始化时规定一个数目,然后计算调用了CyclicBarrier.await()进入等待的线程数。当线程数达到了这个数目时,所有进入等待状态的线程被唤醒并继续。
CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。
CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。