CountDownLatch 使用
CountDownLatch 是一种同步辅助工具, 它允许一个或多个线程等待 直到其它线程的一组操作完成。JDK 1.5加入 。
给定count可以获取CountDownLatch对象。类似于一种记数器,通过getCount()可获知还有多少线程没有执行完成。调用await()方法表示进入阻塞,直到count变成0, 程序方可执行下去。

主线程Tm,调用具体执行业务内容的异步线程组(T0,T1,T2,T3),接下来调用await()方法,让主线程进行等待中。 当前count=4。 异步线程组中的每个线程执行完成后,都 会调用countDown(),表示对count进行减1操作。当四个线程全部执行完成,count==0,则主线程Tm继续往下执行。
构造函数:CountDownLatch latch = new CountDownLatch(count)
需要注意的是,初始化CountDownLatch时的count必需与异步线程组的线程数保持一致,线程数多或少于count,会出现永远等待或业务没有执行完成主线程就往下执行了。
主要的应用场景: 一个业务分多步骤,每个步骤中又分多个并行子模块,子模块全部完成才能进行到下一步。 比如,一张综合性报表是由几张小报表汇总而成,必需要先执行完所有的小报表,方可执行综合性报表汇总。
核心方法:
countDown(): 减少计数, 如果计数为0,则释放所有的等待线程。 如果计数大于0,则进行计数减1; 如果计数=0,则什么都不会发生。
await():线程阻塞。1、计数count=0,2、线程发生interrupt异常。 如果计数=0,则方法立即返回。
await(long timeout, TimeUnit unit):线程阻塞。1、计数count=0;2、线程发生interrupt异常;3、等待超时。
代码实现:
第一种:
public void run1(){
LocalDateTime beginTime = LocalDateTime.now();
Thread[] threads = new Thread[10];
CountDownLatch latch = new CountDownLatch(threads.length);
for (int i=0;i<threads.length;i++){
threads[i] = new Thread(()->{
/**
* 执行业务流程
*/
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
System.out.println(LocalDateTime.now()+"==="+Thread.currentThread().getName());
},"t"+i);
}
for (Thread t : threads){
t.start();
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(beginTime+"---------end latch>>>>"+LocalDateTime.now());
}
第二种:使用线程池
public void run2() {
LocalDateTime beginTime = LocalDateTime.now();
int threadCount = 10 ;
CountDownLatch doneLatch = new CountDownLatch(threadCount);
Executor executor = Executors.newFixedThreadPool(threadCount);
for (int i = 0; i < threadCount; i++) {
executor.execute(new WorkRunnable(doneLatch, i));
}
try {
doneLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(beginTime+"---------end latch>>>>"+LocalDateTime.now());
}
class WorkRunnable implements Runnable {
private CountDownLatch latch ;
private int index;
public WorkRunnable(CountDownLatch latch, int index){
this.latch = latch;
this.index = index;
}
@Override
public void run() {
/**
* 执行业务流程
*/
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
System.out.println(LocalDateTime.now()+" => "+index);
}
}

浙公网安备 33010602011771号