CyclicBarrier介绍
作用
它允许一组线程相互等待,直到到达某个公共屏障点。
业务场景
CyclicBarrier主要是实现了多个线程之间相互等待,直到所有的线程都满足了条件之后各自才能继续执行后续的操作,描述的多个线程内部相互等待的关系。
使用
- 初始化:用一个给定的计数器来初始化。
- await():调用
await
方法的线程会一直处于阻塞状态,且计数器加1,当计数器的值达到设置的初始值时,所有因调用await进入等待状态的线程被唤醒,继续执行后续操作。
CyclicBarrier 与 CountDownLatch 区别
- CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的
- CountDownLatch 参与的线程的职责是不一样的,有的在倒计时,有的在等待倒计时结束。CyclicBarrier 参与的线程职责是一样的。
例子
import java.util.concurrent.CyclicBarrier;
class FooBar {
private int n;
private CyclicBarrier barrier = new CyclicBarrier(2);
private volatile int num = 0;
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
try {
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
// printFoo.run() outputs "foo". Do not change or remove this line.
while(num != 0) {}
printFoo.run();
num = 1;
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
try {
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
// printBar.run() outputs "bar". Do not change or remove this line.
while (num != 1) {}
printBar.run();
num = 0;
}
}
}
效果:两个不同的线程将会共用一个 FooBar 实例。其中一个线程将会调用 foo() 方法,另一个线程将会调用 bar() 方法,以确保 “foobar” 被输出 n 次。