CountDownLatch 学习笔记
1. 概念
CountDownLatch是在JDK 1.5的时候被引入的,位于java.util.concurrent并发包中,CountDownLatch叫做闭锁,也叫门闩。允许一个或多个线程一直等待,直到其他线程执行完成后再执行。
2.工作原理
CountDownLatch通过一个计数器来实现的。计数器的初始化值为线程的数量。每当一个线程完成自己的任务后,计数器的值就相应的减1.当计数器的值减到0时,表示所有的线程都已经完成任务。然后在CountDownLatch上等待的线程就可以恢复执行接下来的任务。
3. 常见方法
- public CountDownLatch(int count)
CountDownLatch接收一个int型参数,表示要等待的工作线程的个数。
- public void await()
使用当前线程进入同步队列进行等待,直到计数器的值减到0或者当前线程被中断,当前线程就会被唤醒。
- public boolean await(Long timeout,TimeUnit unit)
@Slf4j
public class CountDownLatchTest {
//线程总数
private final static int threadCount = 200;
public static void main(String[] args) throws Exception {
//创建固定线程数的线程池
ExecutorService exec = Executors.newFixedThreadPool(threadCount);
//如果有n个子线程,则指定CountDownLatch的计数器为n
final CountDownLatch countDownLatch = new CountDownLatch(threadCount);
//提交到线程池
for (int i = 0; i < threadCount; i++) {
exec.execute(()->{
try{
System.out.println("子线程:"+Thread.currentThread().getName()+"开始执行");
//模拟每个线程处理业务,耗时一秒钟
TimeUnit.SECONDS.sleep(1);
System.out.println("子线程:"+Thread.currentThread().getName()+"执行完成");
//当前线程调用此方法,则计数减一
countDownLatch.countDown();
}catch (Exception e){
e.printStackTrace();
}
});
}
// 阻塞当前线程(此例子就是main主线程), 直到计数器的值为0,主线程才开始处理
countDownLatch.await();
System.out.println("等待子线程执行完毕,主线程 : "+ Thread.currentThread().getName()+"开始执行,此时CountDownLatch的计数器为 :" + countDownLatch.getCount());
//销毁线程
exec.shutdown();
// final int threadNum = i;
// exec.execute(() ->{
// try{
// test(threadNum);
// }catch (Exception e){
// log.error("exception",e);
// }finally {
// countDownLatch.countDown();
//
// }
// });
//
// countDownLatch.await();
// log.info("finish");
// exec.shutdown();
}
private static void test(int threadNum) throws Exception{
Thread.sleep(100);
log.info("{}",threadNum);
Thread.sleep(100);
}
}