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

打印结果如下:

 

 

 

 

 

posted @ 2016-04-10 11:24  冬至饮雪  阅读(5717)  评论(1编辑  收藏  举报