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

  

 

posted @ 2018-03-03 12:04  EvilTuzki  阅读(126)  评论(0编辑  收藏  举报