简介
这个类的中文意思是“循环栅栏”。大概的意思就是一个可循环利用的屏障。它的作用就是会让所有线程都等待完成后才会继续下一步行动。CyclicBarrier的计数器更像一个阀门,需要所有线程都到达,然后继续执行,计数器递增,提供reset功能,可以多次使用。
举个例子,就像生活中我们会约朋友们到某个餐厅一起吃饭,有些朋友可能会早到,有些朋友可能会晚到,但是这个餐厅规定必须等到所有人到齐之后才会让我们进去。这里的朋友们就是各个线程,餐厅就是 CyclicBarrier。
代码语言:javascript复制public CyclicBarrier(int parties)
public CyclicBarrier(int parties, Runnable barrierAction)
parties是参与线程的个数
第二个构造方法有一个Runnable参数,这个参数的意思是最后一个到达线程要做的任务
CyclicBarrier字面意思是“可重复使用的栅栏”,CyclicBarrier 相比 CountDownLatch 来说,要简单很多,其源码没有什么高深的地方,它是 ReentrantLock 和 Condition 的组合使用。
CyclicBarrier 可以有不止一个栅栏,因为它的栅栏(Barrier)可以重复使用(Cyclic)。
代码语言:javascript复制public int await() throws InterruptedException, BrokenBarrierException
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
线程调用 await() 表示自己已经到达栅栏
- CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的。
- CountDownLatch 参与的线程的职责是不一样的,有的在倒计时,有的在等待倒计时结束。CyclicBarrier 参与的线程职责是一样的。
使用示例
代码语言:javascript复制import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierTest {
public static void main(String[] args) {
int threadNum = 5;
CyclicBarrier barrier = new CyclicBarrier(threadNum, new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() " 完成最后任务");
}
});
for(int i = 0; i < threadNum; i ) {
new TaskThread(barrier).start();
}
}
static class TaskThread extends Thread {
CyclicBarrier barrier;
public TaskThread(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println(getName() " 到达栅栏 A");
barrier.await();
System.out.println(getName() " 冲破栅栏 A");
Thread.sleep(2000);
System.out.println(getName() " 到达栅栏 B");
barrier.await();
System.out.println(getName() " 冲破栅栏 B");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
执行结果
Thread-3 到达栅栏 A
Thread-4 到达栅栏 A
Thread-0 到达栅栏 A
Thread-2 到达栅栏 A
Thread-1 到达栅栏 A
Thread-0 完成最后任务
Thread-0 冲破栅栏 A
Thread-3 冲破栅栏 A
Thread-4 冲破栅栏 A
Thread-1 冲破栅栏 A
Thread-2 冲破栅栏 A
Thread-1 到达栅栏 B
Thread-2 到达栅栏 B
Thread-4 到达栅栏 B
Thread-0 到达栅栏 B
Thread-3 到达栅栏 B
Thread-3 完成最后任务
Thread-3 冲破栅栏 B
Thread-1 冲破栅栏 B
Thread-2 冲破栅栏 B
Thread-4 冲破栅栏 B
Thread-0 冲破栅栏 B
从打印结果可以看出,所有线程会等待全部线程到达栅栏之后才会继续执行,并且最后到达的线程会完成 Runnable 的任务。