多线程与并发Java-多线程

并发工具类之CyclicBarrier(栅栏)

2020-12-10  本文已影响0人  逍遥白亦

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();
    }
}

上一篇 下一篇

猜你喜欢

热点阅读