JAVA concurrent包学习--CountDownLatch

java concurrent包学习–CountDownLatch

CountDownLatch简介

CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。

CountDownLatch方法列表

CountDownLatch(int count)
构造一个用给定计数初始化的 CountDownLatch。

// 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。
void await()
// 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。
boolean await(long timeout, TimeUnit unit)
// 递减锁存器的计数,如果计数到达零,则释放所有等待的线程。
void countDown()
// 返回当前计数。
long getCount()
// 返回标识此锁存器及其状态的字符串。
String toString()

个人理解

CountDownLatch 相当于设置了一道有count个闩的门(当闩为0时 门将打开)
执行await()操作的线程都被堵在门前,等待门被打开
执行await(long timeout, TimeUnit unit)操作的线程 若指定的时间内门还未打开, 则该方法抛出异常不再等待

当执行countDown()操作时 相当于减少一个闩(count–)
当闩(count)的数量为0时(门被打开) 会唤醒所有执行await(?)操作的线程 执行后续操作

使用场景

实现最大的并行性:有时我们想同时启动多个线程,实现最大程度的并行性。例如,我们想测试一个单例类。如果我们创建一个初始计数为1的CountDownLatch,并让所有线程都在这个锁上等待,那么我们可以很轻松地完成测试。我们只需调用 一次countDown()方法就可以让所有的等待线程同时恢复执行。

开始执行前等待n个线程完成各自任务:例如应用程序启动类要确保在处理用户请求前,所有N个外部系统已经启动和运行了。

死锁检测:一个非常方便的使用场景是,你可以使用n个线程访问共享资源,在每次测试阶段的线程数目是不同的,并尝试产生死锁。

示例代码(java 1.8)

public static void main(String[] args) {
        CountDownLatch begin = new CountDownLatch(1);
        CountDownLatch end = new CountDownLatch(10);

        for (int i = 0; i < 10; i++) {
            int j = i;
            new Thread(()->{
                try {
                    System.out.println(String.format("runner:%s wait for begin...", j));
                    begin.await();
                    System.out.println(String.format("runner:%s begin run...", j));

                    long st = System.currentTimeMillis();

                    Thread.sleep(100+new Random().nextInt(900));
                    long et = System.currentTimeMillis();

                    System.out.println(String.format("runner:%s run over cost:%sms", j, (et-st)));
                    end.countDown();
                } catch (Exception e) {
                }
            }).start();
        }

        try {
            Thread.sleep(1000);
        } catch (Exception e) {
        }

        System.out.println("game begin ...");
        begin.countDown();

        try {
            //end.await(500, TimeUnit.MILLISECONDS);
            end.await();
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("game end.");
    }

输出结果

runner:5 wait for begin...
runner:2 wait for begin...
runner:6 wait for begin...
runner:1 wait for begin...
runner:7 wait for begin...
runner:0 wait for begin...
runner:4 wait for begin...
runner:3 wait for begin...
runner:9 wait for begin...
runner:8 wait for begin...
game begin ...
runner:2 begin run...
runner:5 begin run...
runner:6 begin run...
runner:1 begin run...
runner:7 begin run...
runner:0 begin run...
runner:4 begin run...
runner:3 begin run...
runner:9 begin run...
runner:8 begin run...
runner:0 run over cost:133ms
runner:9 run over cost:414ms
runner:6 run over cost:437ms
runner:1 run over cost:475ms
runner:3 run over cost:551ms
runner:4 run over cost:557ms
runner:5 run over cost:566ms
runner:8 run over cost:634ms
runner:7 run over cost:662ms
runner:2 run over cost:708ms
game end.

参考博文

博文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值