CountDownLatch思考

2019-12-18  本文已影响0人  追梦小蜗牛
person-walking-on-street-3325720.jpg

简介:

CountDownLatch是并发包的一个类,我个人的理解是它是为了解决多个线程间协作的问题的或者一个大的任务分割成多个小任务,然后用多个子线程去并行完成,当所有的子任务都完成之后,主流程才继续执行...一般解决线程间的协作问题的方法有,像原始的wait、notify方法,还有join等,不过这些都是一对一的,今天的主角解决的是多对多的协作问题。

类图:

CountDownLatch.png

从类图上面可以获取到一些关键信息:

举例:

例子其实也都是源码上面官方的,感觉人家写的更有代表性和通用性,所以就拿过来分析了。

场景1:

A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
一个主任务在执行业务的过程中,需要等待一些中间业务执行完成,而这些中间业务为了提高效率,可以采用多个线程来完成,当所有这些中间业务都执行完了之后,主任务才继续运行下面的业务逻辑。
例子1:

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch startSignal = new CountDownLatch(1);
        CountDownLatch doneSignal = new CountDownLatch(5);
        System.out.println(Thread.currentThread().getName() + "正在工作......");
        for (int i = 0; i < 5; i++) {//创建5个子任务,并启动
            new Thread(new Worker(startSignal, doneSignal)).start();
        }
        startSignal.countDown();//由于count是1,所以调用countDown一次就变成0了,其他由于调用startSignal的await方法阻塞的线程都会恢复运行
        doneSignal.await();//子任务在运行,当前主任务阻塞,需要等待所有的子任务都执行完毕之后,才能接着运行下面的业务代码
        System.out.println("所有的子任务都执行完毕了。");
        System.out.println(Thread.currentThread().getName() + "工作也已经完成。");
    }

    static class Worker implements Runnable {

        private final CountDownLatch startSignal;
        private final CountDownLatch doneSignal;

        public Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
            this.startSignal = startSignal;
            this.doneSignal = doneSignal;
        }

        @Override
        public void run() {
            try {
                startSignal.await();//调用await方法的当前线程会阻塞
                System.out.println(Thread.currentThread().getName() + "开始工作......");
                doneSignal.countDown();//每一个线程执行完毕的时候,都会调用一次doneSignal.countDown方法,做一次减法
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

场景2:

Another typical usage would be to divide a problem into N parts,describe each part with a Runnable that executes that portion and counts down on the latch
场景是把一个大的任务分割成N个小任务,然后这N个小任务提交给线程池处理,负责协调的线程等待,直到它们都完成。

public static void main(String[] args) throws InterruptedException {
        CountDownLatch doneSignal = new CountDownLatch(5);
        Executor executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 5; i++) {
            executor.execute(new Worker(doneSignal,i));
        }
        doneSignal.await();
    }

    static class Worker implements Runnable {

        private CountDownLatch doneSignal;
        private int i;

        public Worker(CountDownLatch doneSignal, int i) {
            this.doneSignal = doneSignal;
            this.i = i;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+" 正在工作......");
            doneSignal.countDown();
        }
    }

总结:

越来越感觉Java里面的东西好多呀,要想Hold住全场,还需更多努力呀。先是一个点一个点的突破,然后经常性的串一串,连贯一下知识,不至于让知识太零碎。这样在解决复杂问题的时候,才会游刃有余,一点一点突破,一点一点进步。
缺乏自信是因为害怕出丑,出洋相,被拒绝,被嘲笑,被鄙视。每个人都不可能不会被嘲笑、出丑,接受这个事实,拥抱这个事实,坦然接受就不会害怕了。

上一篇下一篇

猜你喜欢

热点阅读