一 点睛
1 定义
CyclicBarrier 可以用于解决多个线程之间的相互等待问题。CyclicBarrier 的使用场景是,每个线程在执行时,都会碰到屏障,该屏障会拦截所有线程的执行(通过 await() 方法实现);当指定数量的线程全部就位时,所有的线程再跨过屏障同时执行。
2 CountDownLatch 与 CyclicBarrier 的区别
假设有A、B、C 3 个线程,其中 C是最后一个加入的线程。
- CountDownLatch:可以实现当 A 和 B 全部执行完毕后,C 再去执行。
- CyclicBarrier :可以实现 A、B 等到 C 就绪后(await() 表示就绪),A、B、C 三者再同时去执行。
二 代码
1 问题描述
3个人去开会,只有当 3 个人都抵达之后,会议才开始。换句话说,当最后一个人抵达后,会议就开始。
2 代码
package concurrent;
import java.io.IOException;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestCyclicBarrier {
static class MyThread implements Runnable {
// 用于控制会议开始的屏障
private CyclicBarrier barrier;
// 参会人员
private String person;
public MyThread(CyclicBarrier barrier, String name) {
this.barrier = barrier;
this.person = name;
}
@Override
public void run() {
try {
Thread.sleep((int) (10000 * Math.random()));
System.out.println(person + " 已经到会...");
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(person + " 开始会议...");
}
}
public static void main(String[] args) throws IOException, InterruptedException {
// 将屏障设置为 3,即当有 3 个线程执行到await()时,再同时释放
CyclicBarrier barrier = new CyclicBarrier(3);
ExecutorService executor = Executors.newFixedThreadPool(3);
//三个人去开会
executor.submit(new MyThread(barrier, "zs"));
executor.submit(new MyThread(barrier, "ls"));
executor.submit(new MyThread(barrier, "ww"));
executor.shutdown();
}
}
3 测试
ww 已经到会...
zs 已经到会...
ls 已经到会...
ls 开始会议...
ww 开始会议...
zs 开始会议...