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成绩
    英语全体学生成绩汇总计算
    语文全体学生成绩汇总计算
    

      

  • 相关阅读:
    tomcat feign rocketmq 最大线程数
    rocketmq
    使用docker在linux上安装oracle数据库
    dnf 腾讯 解人脸
    记一次mysql慢查询优化
    python运行内存分析
    【转】【WPF】WPF强制刷新界面
    【转】【WPF】Grid显示边框线
    流媒体服务新手入门教程03--音视频基础
    流媒体服务新手入门教程02--m7s环境搭建
  • 原文地址:https://www.cnblogs.com/eviltuzki/p/8496245.html
Copyright © 2011-2022 走看看