CyclicBarrier (cyclic循环的 barrier栅栏)
1.使用场景
一个线程组的线程需要等待所有线程完成任务后再继续执行下一次任务,
常用于多线程计算数据,最后合并计算结果。
实际场景案例
1️⃣多人游戏房间,每个玩家都要等待其他玩家到齐后才开始一局游戏。
2️⃣旅游团去旅游,每个游客都要等待其他游客到齐集合后,导游才发放门票。
3️⃣坐长途汽车,每个乘客要等待其他人都上车后,司机才开车
4️⃣拼多多拼团,购物团凑够人数后,商家才接单发货;这一波人拼单成功后,下一波人又来拼团。。。
2.关键点解释
用Cyclic修饰Barrier是因为,所有线程到达栅栏并释放后,这个栅栏可以再次使用。
public CyclicBarrier(int parties, Runnable barrierAction)
CyclicBarrier循环栅栏,相当于旅游团的集合地点;
parties 参与线程的个数,相当于游客数目;
Runnable barrierAction最后一个线程到达后程序要做的任务(栅栏任务),相当于发放门票的任务。
❓如何表示1个线程已经到达栅栏?
💢用 线程.await() 表示自己已经到达栅栏
3.用法实践
public static void main(String[] args) {
//创建1个循环栅栏
//cyclicBarrier 相当于集合地点,3 指3个游客, new Runnable相当于发放门票的动作
CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
@Override
public void run() {
//发放门票的具体细节
System.out.println("导游开始发门票!"+new Date());
}
});
// 调用3个游客线程
new PersonA(cyclicBarrier, "A", 3L).start();
new PersonB(cyclicBarrier, "B", 5L).start();
new PersonC(cyclicBarrier, "C", 6L).start();
}
package jucdemo;
/**
* 用3个人表示3个线程
* PersonA 表示第一个人,用(extends Thread)表示这是1个线程
* @author me
*/
import java.util.Date;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
//考虑到线程组里每个子线程可能执行的Task不同,建议企业开发中用extends Thread实现一个线程
public class PersonA extends Thread{
//集合点
private CyclicBarrier cBarrier;
//游客姓名
private String name;
//走路用时
private long duration;
public PersonA(CyclicBarrier cBarrier, String name, long duration) {
this.cBarrier = cBarrier;
this.name = name;
this.duration = duration;
}
//走路动作
@Override
public void run() {
try {
System.out.println(name+"开始走路"+new Date());
//走路用时
Thread.sleep(duration*1000);
System.out.println(name+"到达集合点"+new Date());
//用 线程.await() 表示自己已经到达栅栏
cBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
执行结果: 可以发现到达栅栏用时最长的一个线程的结束时间-即程序最终执行栅栏任务的开始时间
A开始走路Thu Sep 24 22:43:16 CST 2020
C开始走路Thu Sep 24 22:43:16 CST 2020
B开始走路Thu Sep 24 22:43:16 CST 2020
A到达集合点Thu Sep 24 22:43:19 CST 2020
B到达集合点Thu Sep 24 22:43:21 CST 2020
C到达集合点Thu Sep 24 22:43:22 CST 2020
导游开始发门票!Thu Sep 24 22:43:22 CST 2020