并发编程【CyclicBarrier】
一、使用场景
通过它可以实现让一组线程等待至某个状态之后再全部同时执行。
CyclicBarrier 中最重要的方法就是 await 方法,它有 2 个重载版本:
// 用来挂起当前线程,直至所有线程都到达指定状态再同时执行后续任务
public int await();
// 让这些线程等待至一定的时间,如果还有线程没有到达指定状态就直接让已经到达指定状态的线程执行后续任务。
public int await(long timeout, TimeUnit unit);
二、代码实现
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, ()->{
System.out.println("已集齐7颗龙珠,开始召唤神龙...");
});
for(int i=1; i<=7; i++){
final int tempInt = i;
new Thread(()->{
System.out.println("线程"+Thread.currentThread().getName() + " 收集到第" + tempInt + "颗龙珠");
try {
cyclicBarrier.await();
System.out.println("神龙召唤成功,开始执行线程" + Thread.currentThread().getName()+"的代码");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}, String.valueOf(i)).start();
}
}
}
运行结果:
线程1 收集到第1颗龙珠
线程2 收集到第2颗龙珠
线程3 收集到第3颗龙珠
线程4 收集到第4颗龙珠
线程5 收集到第5颗龙珠
线程6 收集到第6颗龙珠
线程7 收集到第7颗龙珠
已集齐7颗龙珠,开始召唤神龙...
神龙召唤成功,开始执行线程7的代码
神龙召唤成功,开始执行线程1的代码
神龙召唤成功,开始执行线程3的代码
神龙召唤成功,开始执行线程2的代码
神龙召唤成功,开始执行线程6的代码
神龙召唤成功,开始执行线程4的代码
神龙召唤成功,开始执行线程5的代码
三、大致原理分析
每个线程执行完自己独有的代码后,会修改 cyclicBarrier 的值,对其进行加 1 操作,然后等待其它线程。
当 cyclicBarrier 的值达到指定的条件后(此处为7),就会执行
new CyclicBarrier()
中指定的线程,然后其它的线程再次开始执行,这些线程需要重新进行抢占,所以顺序不能确定。
Java新手,若有错误,欢迎指正!