JUC系列——CountDownLatch

简介

CountDownLatch 是一个倒数器,像是一个发令枪。

  • 构造参数 N 倒计时起始数据(N=3,则从3开始数,3,2,…)
  • countDown()方法就是执行一次倒数,N就减一
  • await() 在当前计数到达零之前,await 方法会一直受阻塞

所以可以利用这一特性,同时唤醒多个等待的线程。

示例代码实现:

  1. 提交5个任务
  2. 前3个同时开始执行
  3. 任务提交完毕后,主线程阻塞,直到有4个任务完成
  4. 然后主线程继续执行
  5. 等待线程池优雅停止

代码

public class CountDownLatchDemo {

    public static void main(String[] args) throws Exception {

        ExecutorService exe =Executors.newFixedThreadPool(5);

        /**
         * 前3个一起执行
         * 4个做完 有信号
         */
        CountDownLatch startLatch = new CountDownLatch(3);
        CountDownLatch doneSignal = new CountDownLatch(4);

        for (int i = 0; i < 5; i++) {
            exe.execute(new WaitTask(startLatch, doneSignal));
            startLatch.countDown();

            TimeUnit.MILLISECONDS.sleep(300);
        }

        PrintUtil.print("waiting four done ");
        doneSignal.await();
        PrintUtil.print("four done ");
        exe.shutdown();
    }
}


public class WaitTask implements Runnable {
    private static int counter = 0;
    private final int id = counter++;

    private final CountDownLatch latch;
    private final CountDownLatch doneSignal;

    public WaitTask(CountDownLatch latch, CountDownLatch doneSignal) {
        this.latch = latch;
        this.doneSignal = doneSignal;
        PrintUtil.print(this + "construct ");
    }

    @Override
    public void run() {
        try {
            latch.await();
            PrintUtil.print(this + "after run await");

            working();
        } catch (InterruptedException e) {
            PrintUtil.print("InterruptedException" + this);
        }

        doneSignal.countDown();
        PrintUtil.print(this + "done!");
    }

    @Override
    public String toString() {
        return "WaitTask{" +
                "id=" + id + "} :";
    }

    private void working() throws InterruptedException {
        PrintUtil.print(this + "working");
        Thread.sleep(1000);
    }
}

优雅停止
exe.shutdown();
线程池不再接受新提交的任务,但会执行完所有已提交的任务,然后退出。

结果

WaitTask{id=0} :construct
WaitTask{id=1} :construct
WaitTask{id=2} :construct
WaitTask{id=2} :after run await
WaitTask{id=0} :after run await
WaitTask{id=1} :after run await
WaitTask{id=0} :working
WaitTask{id=2} :working
WaitTask{id=1} :working
WaitTask{id=3} :construct
WaitTask{id=3} :after run await
WaitTask{id=3} :working
WaitTask{id=4} :construct
WaitTask{id=4} :after run await
WaitTask{id=4} :working
waiting four done
WaitTask{id=0} :done!
WaitTask{id=1} :done!
WaitTask{id=2} :done!
WaitTask{id=3} :done!
four done
WaitTask{id=4} :done!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值