CyclicBarrier的概念理解:
CyclicBarrier的字面上的意思是可循环的屏障,是java并发包java.util.concurrent 里的一个同步工具类,在我下载的JDK1.6的中文文档里对他的解释是:
大体意思就是:让一组线程到达一个屏障,一个集合点时,被阻塞,直到所有的线程都到了这个集合点时,屏障才会打开,然后线程才能继续往下执行.举个简单的例子就是:旅游团带着一帮人参观景点,规定在下一个景点A处集合,于是导游就在景点A等着大家,导游就是这个集合点或者说屏障,直到所有的游客集合完毕,导游才会带着大家继续参观下一个景点B.
CyclicBarrier的使用:
CyclicBarrier有两个构造函数:
CyclicBarrier(int parties); int类型的参数表示有几个线程来参与这个屏障拦截,(拿上面的例子,即有几个人跟团旅游);
CyclicBarrier(int parties,Runnable barrierAction);当所有线程到达一个屏障点时,优先执行barrierAction这个线程.
最重要的一个方法:
await();每个线程调用await(),表示我已经到达屏障点,然后当前线程被阻塞,(拿上面的例子讲就是游客A表示到达了景点A,然后他就在那儿等着大家到齐).
应用场景:
CyclicBarrier可以用于多线程计算数据,最后合并计算结果的场景,我没怎么用过这个类,所有只能简单模拟一个功能.
需求描述:
假设现在需要计算3个学生的平均成绩,
每个学生共有三门成绩.
步骤是:先计算出每个学生的平均成绩
再根据每个学生的平均成绩来计算三个同学的平均成绩
使用CyclicBarrier
package com.wang.thread1; import java.util.Set; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 假设现在需要计算3个学生的平均成绩, *每个学生共有三门成绩 *步骤是:先计算出每个学生的平均成绩 *再根据每个学生的平均成绩来计算所有有同学的平均成绩 *使用CyclicBarrier * @author Administrator * */
public class CyclicBarrier1 implements Runnable{ //创建初始化3个线程的线程池
private ExecutorService threadPool=Executors.newFixedThreadPool(3); //创建3个CyclicBarrier对象,执行完后执行当前类的run方法
private CyclicBarrier cb=new CyclicBarrier(3,this); //保存每个学生的平均成绩
private ConcurrentHashMap<String, Integer> map=new ConcurrentHashMap<String,Integer>(); public void count(){ for(int i=0;i<3;i++){ threadPool.execute(new Runnable(){ @Override public void run() { //计算每个学生的平均成绩,代码略()假设为60~100的随机数
int score=(int)(Math.random()*40+60); map.put(Thread.currentThread().getName(), score); System.out.println(Thread.currentThread().getName()+"同学的平均成绩为"+score); try { //执行完运行await(),等待所有学生平均成绩都计算完毕
cb.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } }); } } @Override public void run() { int result=0; Set<String> set = map.keySet(); for(String s:set){ result+=map.get(s); } System.out.println("三人平均成绩为:"+(result/3)+"分"); } public static void main(String[] args) { CyclicBarrier1 cb=new CyclicBarrier1(); cb.count(); } }
打印结果如下: