CyclicBarrier要做的事就是让一组线程到达一个屏障是被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。
CyclicBarrier默认的构造方法是CyclicBarrier(int parties), 其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。
CyclicBarrier 是N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
public class CB {
private static CyclicBarrier cyclicBarrier=new CyclicBarrier(3);//创建3个屏障
public static void main(String args[]) throws Exception{
new Thread(new Runnable() {
public void run() {
for(int i=0;i<3;i++){
System.out.println("啊哈哈哈"+i);
try {
cyclicBarrier.await(); //到达屏障 阻塞当前线程
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
cyclicBarrier.await(); //到达屏障 阻塞当前线程
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("fsdfsd fdsfsd ");
}
}).start();
cyclicBarrier.await(); //第三个线程到达屏障,放开所有被拦截的屏障
// cyclicBarrier.reset();
System.out.println("cdsac ");
}
}
CyclicBarrier还提供了一更高级的构造方法CyclicBarrier(int parties,Runable action), 用于在线程达到屏障,优先执行action线程,方便处理更复杂的业务逻辑 :
public class MyCyclicBarrier implements Runnable{
//创建初始化3个线程的线程池
private ExecutorService threadPool= Executors.newFixedThreadPool(3);
//创建3个CyclicBarrier对象,执行完后执行当前线程
private CyclicBarrier cb=new CyclicBarrier(3,this);
//保存每个学生的平均成绩
private ConcurrentHashMap<String, Integer> map=new ConcurrentHashMap<String,Integer>();
public void count(){
for(int i=0;i<3;i++){
threadPool.execute(new Runnable(){
public void run() {
//计算每个学生的平均成绩,代码略()假设为60~100的随机数
int score=(int)(Math.random()*40+60);
map.put(Thread.currentThread().getName(), score);
//执行完运行await(),等待所有学生平均成绩都计算完毕
try {
cb.await(); //全部阻塞在这里,直到循环到最后一次,所有线程到达屏障,但是要先执行主线程.
System.out.println(Thread.currentThread().getName()+"同学的平均成绩为"+score);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
public void run() {
int result=0;
Set<String> set = map.keySet();
for(String s:set){
result+=map.get(s);
}
System.out.println("三人平均成绩为:"+(result/3)+"分");
}
public static void main(String[] args) {
MyCyclicBarrier cb=new MyCyclicBarrier();
cb.count();
}
}
CyclicBarrier.awit()在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
CyclicBarrier.getNumberWaiting()返回当前在屏障处等待的参与者数目。
CyclicBarrier.isBroken() 查询此屏障是否处于损坏状态。
CyclicBarrier.reset() 将屏障重置为其初始状态。