1. 定义
栅栏屏障,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。
2. 常用方法
2.1 构造方法
public CyclicBarrier(int parties)
其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。
public CyclicBarrier(int parties,
Runnable barrierAction)
创建一个新的 CyclicBarrier,当给定数量的线程(线程)正在等待时,它将跳闸,当屏障跳闸时执行给定的屏障动作,由最后一个进入屏障的线程执行。
2.2 await()方法
public int await()
throws InterruptedException,
BrokenBarrierException
3. 应用场景
可以用于多线程计算数据,最后合并计算结果的场景。例如,假设有三个同学,先计算出每个学生的平均成绩,再计算成三个同学总体的平均成绩。
示例代码:
package CyclicBarrier.example;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class CyclicBarrierDemo implements Runnable {
//初始化三个线程的线程池
private ExecutorService executorService = Executors.newFixedThreadPool(3);
//存储每个学生的平均成绩
private ConcurrentHashMap<String, Integer> scores = new ConcurrentHashMap<>();
private CyclicBarrier cyclicBarrier = new CyclicBarrier(3, this::run);
public void count(){
for (int i=0; i<3; i++){
executorService.execute(() ->{
int score = (int)(Math.random()*40 +60);
scores.put(Thread.currentThread().getName(), score);
System.out.println(Thread.currentThread().getName() + "同学的成绩为" + score);
try {
//等待最后一个线程计算平均值
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
});
}
executorService.shutdown();
}
@Override
public void run() {
final int[] result = {0};
scores.forEach((name, score) ->{
result[0] += score;
});
System.out.println("三人平均成绩为: " + (result[0] /3));
}
public static void main(String[] args) {
CyclicBarrierDemo cyclicBarrierDemo = new CyclicBarrierDemo();
cyclicBarrierDemo.count();
}
}
网友评论