zoukankan      html  css  js  c++  java
  • 学习CountDownLatch

    对比 使用CyclicBarrier 

    上次用Barrier方式实现了线程等待一组完成,这次用CountDownLatch来实现

    我的理解CountDownLatch 采用的方式是计数器方式,每执行完一个线程,计数器减一,等计数器减到0的时候,之前等待的线程就可以执行了。

    和Barrier的例子一样,这次是2个线程等待一组完成,代码如下:

    package countdown;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Random;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class Demo {
        public static void main(String[] args) {
            List<String> students = Arrays.asList("Tom","Bill","Dick","Marry","Lily","Harry");
            StudentCalc calc = new StudentCalc();
            CountDownLatch cdl= new CountDownLatch(students.size());//算是个计数器吧
            ExecutorService exec = Executors.newCachedThreadPool();//用线程池方式执行
            exec.execute(new TotalScore(cdl,new StudentCalc("语文")));//汇总任务
            exec.execute(new TotalScore(cdl,new StudentCalc("英语")));//汇总任务
            students.forEach(x->exec.execute(new StudentScore(cdl,calc,x)));//每个学生的任务
            exec.shutdown();//关闭线程池
        }
    }
    
    
    
    class StudentScore implements Runnable{
    
    
        private StudentCalc studentCalc;
        private String studentName;
        private CountDownLatch countDownLatch;
    
        public StudentScore( CountDownLatch cdl, StudentCalc studentCalc, String studentName) {
            this.countDownLatch=cdl;
            this.studentCalc = studentCalc;
            this.studentName = studentName;
        }
    
        @Override
        public void run() {
    
            studentCalc.student(studentName);
            countDownLatch.countDown();//计算之后计数器-1
    
        }
    }
    
    class TotalScore implements Runnable{
        private StudentCalc studentCalc;
        private CountDownLatch countDownLatch;
        TotalScore(CountDownLatch cdl, StudentCalc studentCalc) {
            this.studentCalc = studentCalc;
            this.countDownLatch = cdl;
        }
    
    
        @Override
        public void run() {
            try {
                countDownLatch.await();//先等待所有线程完成
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            studentCalc.total();//总成绩 计算
        }
    }
    
    /**
     * 计算类
     */
    class StudentCalc {
        private String type;
    
        public StudentCalc(String type) {
            this.type = type;
        }
    
        public StudentCalc() {
        }
    
        /**
         * 全部成绩计算完成后,调用汇总
         */
        public void total(){
            System.out.println(type + "全体学生成绩汇总计算");
        }
    
        /**
         * 计算每个学生自己成绩,为了模拟每个学生计算时间不同,使用Thread.sleep区分
         * @param student
         */
        public void student(String student){
            try {
                Thread.sleep(new Random().nextInt(2000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("计算" + student + "成绩");
        }
    }
    

      执行结果如下:

    计算Lily成绩
    计算Bill成绩
    计算Harry成绩
    计算Marry成绩
    计算Dick成绩
    计算Tom成绩
    英语全体学生成绩汇总计算
    语文全体学生成绩汇总计算
    

      

  • 相关阅读:
    Windows移动开发(五)——初始XAML
    hdu5242 上海邀请赛 优先队列+贪心
    iOS开发一行代码系列:一行搞定数据库
    MySQL内存调优
    菜鸟nginx源代码剖析 配置与部署篇(一) 手把手实现nginx &quot;I love you&quot;
    配置JBOSS多实例
    MyBatis对数据库的增删改查操作,简单演示样例
    uva 11605
    ios调用dismissViewController的一个小陷阱
    初识ASP.NET---点滴的积累---ASP.NET学习小结
  • 原文地址:https://www.cnblogs.com/eviltuzki/p/8496245.html
Copyright © 2011-2022 走看看