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

    打印结果如下:

     

     

     

     

     

  • 相关阅读:
    centos 挂载u盘
    如何将网站部署到tomcat根目录下
    seo工具
    mysql 1045 access denied for user********
    div 自适应宽度
    mysql 日志提示 is marked as crashed and should be repaired
    css overflow:hidden无效解决办法
    java 调用 .net webservice
    Java开发笔记(十五)短路逻辑运算的优势
    Java开发笔记(十四)几种运算符的优先级顺序
  • 原文地址:https://www.cnblogs.com/fingerboy/p/5373642.html
Copyright © 2020-2023  润新知