CyclicBarrier是栅栏的意思,线程要越过这个栅栏才能继续执行,但是必须是所有的线程到齐后才能一起越过这个栅栏。主要适用了两个或多个线程的线程组在预定的执行点进行等待,直达线程组中所有的线程都到达执行点再继续执行。
例如一个团队游戏,总共10人参加,其中有一个项目是跨越高墙,跨越高墙高墙后的项目是必须10个人一起参加,缺一不可。那么先跨过高墙的人必须等待。这10个人就相当于10个线程,CyclicBarrier同步对像就相当于高墙。
看下CyclicBarrier的构造函数
public CyclicBarrier(int parties) {
this(parties, null);
}
//parties指定的需经同步的线程数据,barrierAction指定的当所有线程都到达执行点时需要执行的动作
public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;
this.count = parties;
this.barrierCommand = barrierAction;
}
应用实例
//需要同步线程
class TaskThread implements Runnable {
CyclicBarrier cyclicBarrier;
String name;
TaskThread(CyclicBarrier c, String n) {
cyclicBarrier = c;
name = n;
}
public void run() {
System.out.println(name+"到达集合点");
try {
cyclicBarrier.await();//线程阻塞于此,当指定数目的线程都调用此方法后再继续执行
} catch (BrokenBarrierException exc) {
System.out.println(exc);
} catch (InterruptedException exc) {
System.out.println(exc);
}
}
}
//当所有需要同步的线程都到达后
class CyclicBarrierAction implements Runnable {
public void run() {
System.out.println("所有线程均到达集合点");
}
}
public class CyclicBarrierDemo {
public static void main(String args[]) {
CyclicBarrier cb = new CyclicBarrier(3,new CyclicBarrierAction());
System.out.println("Starting");
//下面是创建并启动了三个线程,实际编程中一个是写一个子类而不是在此处,此类只是用来
new Thread(new TaskThread(cb,"ThreadA")).start();
new Thread(new TaskThread(cb,"ThreadB")).start();
new Thread(new TaskThread(cb,"ThreadC")).start();
}
}
输出如下:
Starting
ThreadA到达集合点
ThreadB到达集合点
ThreadC到达集合点
所有线程均到达集合点
如果把CyclicBarrier cb = new CyclicBarrier(3,new CyclicBarrierAction());设为四,即CyclicBarrier cb = new CyclicBarrier(4,new CyclicBarrierAction()),其它地方不变,那么三个线程ThreadA、ThreadB、ThreadC将永久等待,因为需要四个线程都到集合点,有一个没有到。输出如下
Starting
ThreadA到达集合点
ThreadB到达集合点
ThreadC到达集合点