CountDownLatch
一、作用
- CountDownLatchTest是并发编程的工具类,当一个线程需要等待其他一组线程完毕后再执行,就可以使用CountDownLatch,
当线程只需要等待其他一个线程的时候我们一般会使用join,CountDownLatch有点像一个加强版的join。
比如我们有四个线程同时对某个数据源进行分析,我们需要在四个线程执行完后,主线程将分析结果保存到数据库,就可以借助CountDownLatch来实现
二、代码
package com.intellif.mozping.concurrentutil.countdownLatchp;
import com.intellif.mozping.tools.SleepTools;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* @author by mozping
* @Classname CountDownLatchTest
* @Description CountDownLatch测试类
* 初始化了CountDownLatch类,初始化若干个扣除点,比如5个,
* 在主线程中初始化5个业务线程,每个业务线程执行完成后,减去一个扣除点,主线程会等待扣除点为0后才执行,
* 这里每次默认扣除一个扣除点,注意如果初始化了6个扣除点,五个线程只扣除5次,那么主线程就会一直阻塞住
* @Date 2019/1/2 15:51
*/
public class CountDownLatchTest {
private static CountDownLatch countDownLatch = new CountDownLatch(5);
/**
* 主线程
*/
public static void main(String[] args) throws InterruptedException {
for (int i = 1; i <= 5; i++) {
new MyBussinessThread().start();
}
//主线程等待
countDownLatch.await(15, TimeUnit.SECONDS);
System.out.println("主线程等待结束后执行...,剩余扣除点:" + countDownLatch.getCount());
}
/**
* 业务线程
*/
private static class MyBussinessThread extends Thread {
@Override
public void run() {
System.out.println("业务线程 [" + Thread.currentThread().getName() + "] 处理业务...");
//随机休眠10以内的时间
SleepTools.randomSecond(10);
System.out.println("业务线程 [" + Thread.currentThread().getName() + "] 处理业务完毕...");
//完成后扣减一次
countDownLatch.countDown();
}
}
}
三、注意事项
- 这里每个线程执行完毕后会扣除一个扣除点,默认线程数量是5,扣除点可以大于或者等于5,比如根据业务场景,部分线程执行后又多个扣除点,如果线程执行完毕后扣除点没有归零,那么主线程就会阻塞。
四、Tips
- countDownLatch.getCount()可以获取到剩余的扣除数
- await方法可以指定超时时间,避免程序阻塞一直不往下执行
- 注意在创建的子线程中执行任务之后,对CountDownLatch进行扣减,之前在一次代码中,子线程里面有一个while循环,不小心把扣减写到了循环体里面,结果主线程根本无法等到所有的子线程执行完毕,就扣减完了,导致结果不对,后面要注意这点