美文网首页
JUC系列04-CountDownLatch闭锁

JUC系列04-CountDownLatch闭锁

作者: 码蜂窝 | 来源:发表于2019-03-29 00:28 被阅读0次

    1 为什么要使用CountDownLatch

    先通过以下例子了解CountDownLatch到作用

    package com.mafgwo.juc.testvolatile;
    
    import java.util.Random;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.TimeUnit;
    
    /**
     * CountDownLatch使用例子
     */
    public class TestCountDownLatch {
    
        public static void main(String[] args) {
            // 开10个线程打印线程名
            CountDownLatch countDownLatch = new CountDownLatch(10);
            for (int i = 0; i < 10; i++) {
                new Thread(() -> {
                    // 睡眠随机500ms内
                    try {
                        Thread.sleep(new Random().nextInt(500));
                        System.out.println(Thread.currentThread().getName());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        countDownLatch.countDown();
                    }
                }).start();
            }
            try {
                countDownLatch.await(5, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 打印所有线程已处理完
            System.out.println("所有线程已完成");
        }
    
    }
    
    

    其他方式实现线程等待如下

    package com.mafgwo.juc.testvolatile;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 等待线程执行完到其他例子
     */
    public class TestWaitThread {
    
        public static void main(String[] args) {
            List<Thread> threads = new ArrayList<>();
            // 开10个线程打印线程名
            for (int i = 0; i < 10; i++) {
                Thread t = new Thread(() -> {
                    // 睡眠随机500ms内
                    try {
                        Thread.sleep(new Random().nextInt(500));
                        System.out.println(Thread.currentThread().getName());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });
                threads.add(t);
                t.start();
            }
            for (Thread thread : threads) {
                try {
                    thread.join(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 打印所有线程已处理完
            System.out.println("所有线程已完成");
        }
    
    }
    
    

    使用分析

    两者的共同点:都能做到等待全部线程执行完再执行主线程。
    两者的区别:CountDownLatch是使用计数方式,await阻塞主线程,当计数为0则继续执行。Thread.join则会不断检查线程是否存在,存活则调用wait方法阻塞线程,等待线程结束时的notifyAll。
    总结:CountDownLatch主要是用于多线程时需要完成某些线程,再继续往下执行的场景,不需要等待线程关闭,便于在线程池中使用。
    注意事项:第一,CountDownLatch.countDown()方法要放在finally中,避免程序异常未执行减1操作导致不必要的阻塞;第二,CountDownLatch.await方法要设置超时时间,避免某些异常场景下出现死锁。

    来源:码蜂窝-JUC系列04-CountDownLatch闭锁

    相关文章

      网友评论

          本文标题:JUC系列04-CountDownLatch闭锁

          本文链接:https://www.haomeiwen.com/subject/eqxkbqtx.html