java多线程--同步屏障CyclicBarrier的使用
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();
}
}
打印结果如下: