多线程 - CountDownLatch总结
Posted Alex_MaHao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程 - CountDownLatch总结相关的知识,希望对你有一定的参考价值。
问题
当主线程的任务执行,需要依赖多个子线程运行结束后才能往下执行时如何解决,比如文件分段下载,同时开启多个子线程进行文件的分段下载,当下载完成之后,再进行组装。
有一种解决方式,便是在子线程下载完成之后,都进行子线程的回调并判断是否所有子线程都已经执行完毕。
而CountDownLatch
便是java
在1.5提供的解决如上问题的工具类
阿里的ARouter
的拦截器相关,就是用该工具类
概述
CountDownLatch
是通过一个计数器来实现的,计数器的初始值是线程的数量。然后通过调用await()
完成阻塞,每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后阻塞会被打开。
使用
初始化CountDownLatch
并设置子线程数量
CountDownLatch latch = new CountDownLatch(2);
创建子线程并启动,并在子线程结束时,调用countDown()进行计数器更新
es1.execute(new Runnable()
@Override
public void run()
Thread.sleep(3000);
System.out.println("子线程:" + Thread.currentThread().getName() + "执行");
// 核心方法
latch.countDown();
);
主线程进行等待
latch.await();
该方法同时提供了一个重载方法,可以设置阻塞的时间,如果超时,直接执行,跳过阻塞。
public boolean await(long timeout, TimeUnit unit)
CyclicBarrier比对
CountDownLatch
执行一次,完成之后就结束了。CyclicBarrier
可以使用多次。比如有4个线程,每个线程内部都分为3个子任务,而每个线程都需要保持子任务的同步,即4个线程都执行完自己的第一个任务之后,才开始往下执行第二个任务。
例如
@Override
public void run()
try
Thread.sleep(1000);
System.out.println(getName() + " 任务1");
barrier.await();
System.out.println(getName() + " 任务2");
Thread.sleep(1500);
barrier.await();
Thread.sleep(2000);
System.out.println(getName() + " 任务3");
barrier.await();
catch (Exception e)
e.printStackTrace();
多个run
会先打印完任务1
才开始打印任务2
以上是关于多线程 - CountDownLatch总结的主要内容,如果未能解决你的问题,请参考以下文章
Java多线程信号量同步类CountDownLatch与Semaphore
多线程等待所有子线程执行完使用总结——CountDownLatch使用和源码初步分析
多线程之倒计时器CountDownLatch和循环栅栏CyclicBarrier