前面介绍了CountDownLatch的使用,这里再简单介绍一下CyclicBarrier。
CyclicBarrier的主要功能与CountDownLatch一样,也是保证一个或者多个线程等待,直到一组线程全部结束,唯一的区别是:CountDownLatch一旦不可重用,而CyclicBarrier可重用,它有一个await()方法,线程调用await方法后会变成barrier,当所有的线程都变成barrier时,阻塞解除,等待线程开始执行。此外,它有两个构造方法:CyclicBarrier(int parties)和CyclicBarrier(int parties, Runnable barrierAction),这里介绍一下第二个构造函数,第一个参数表示主线程需要等待的线程数量,和CountDownLatch类似,第二个参数是一个barrier action,是在所有线程变成barrier(调用了await)后,开始执行。
下面是示例代码:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierABC {
private static final int N = 3;
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(N,new Runnable() {
@Override
public void run() {
System.out.println("三个线程打印结束,开始执行主线程");
}
});
new Thread(new Print("A", barrier)).start();
new Thread(new Print("B", barrier)).start();
new Thread(new Print("C", barrier)).start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("过了5秒,开始重用barrier");
new Thread(new Print("D", barrier)).start();
new Thread(new Print("E", barrier)).start();
new Thread(new Print("F", barrier)).start();
}
}
class Print implements Runnable {
private CyclicBarrier barrier;
private String name;
Print(String name, CyclicBarrier barrier) {
this.name = name;
this.barrier = barrier;
}
@Override
public void run() {
System.out.println(name);
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
/*
输出结果(备注:ACB和DEF的输出顺序不确定):
A
C
B
三个线程打印结束,开始执行主线程
过了5秒,开始重用barrier
D
E
F
三个线程打印结束,开始执行主线程
*/