学习了解CyclicBarrier

时间:2022-05-31 20:48:33
CyclicBarrier我的理解就是一个线程等待器,用途就是将注册了这个barrier的线程卡在同一个位置,直到注册这个barrier的所有线程都完成之后,继续执行。
下面是一个学习过程中采用的示例,计算每个学生分别的成绩,然后统一汇总计算全班成绩
package cyclic;

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; public class CyclicBarrierDemo {
public static void main(String[] args) {
List<String> students = Arrays.asList("Tom","Bill","Dick","Marry","Lily","Harry");
StudentCalc calc = new StudentCalc();
CyclicBarrier cyclicBarrier = new CyclicBarrier(students.size(),new TotalScore(calc));//所有注册cyclicBarrier的线程完成后才会执行TotalScore线程
students.forEach(x-> new Thread(new StudentScore(cyclicBarrier,calc,x)).start());
System.out.println("我在主线程");//对后续无影响
}
} class TotalScore implements Runnable{
private StudentCalc studentCalc; TotalScore(StudentCalc studentCalc) {
this.studentCalc = studentCalc;
} @Override
public void run() {
studentCalc.total();//总成绩 计算
}
} class StudentScore implements Runnable{ private CyclicBarrier barrier;
private StudentCalc studentCalc;
private String studentName; public StudentScore(CyclicBarrier barrier, StudentCalc studentCalc, String studentName) {
this.barrier = barrier;
this.studentCalc = studentCalc;
this.studentName = studentName;
} @Override
public void run() {
studentCalc.student(studentName); try {
this.barrier.await();//计算完成后等待其他线程
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
} /**
* 计算类
*/
class StudentCalc {
/**
* 全部成绩计算完成后,调用汇总
*/
public void total(){
System.out.println("全体学生成绩汇总计算"); } /**
* 计算每个学生自己成绩,为了模拟每个学生计算时间不同,使用Thread.sleep区分
* @param student
*/
public void student(String student){
try {
Thread.sleep(new Random().nextInt(2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("计算" + student + "成绩");
}
}

  示例很简单,具体CyclicBarrier是如何实现的,后面在慢慢研究。

输出结果不固定如下所示:

我在主线程
计算Lily成绩
计算Bill成绩
计算Tom成绩
计算Dick成绩
计算Marry成绩
计算Harry成绩
全体学生成绩汇总计算