Java—CountDownLatch使用详解
2021-01-16 07:14
标签:数值 state 不能 rup map 图片 from thread proc 运行结果: 一个程序中有N个任务在执行,我们可以创建值为N的CountDownLatch,当每个任务完成后,调用一下 代码 运行结果 从运行结果可以看出: 代码 运行结果 从运行结果可以看出,主线程是等待其他线程运行了5次结束后就打印了 Java—CountDownLatch使用详解 标签:数值 state 不能 rup map 图片 from thread proc 原文地址:https://www.cnblogs.com/Andya/p/12925634.htmlCountDownLatch介绍
CountDownLatch概述
CountDownLatch
一般用作多线程倒计时计数器,强制它们等待其他一组(CountDownLatch
的初始化决定)任务执行完成。CountDownLatch
初始化后计数器值递减到0的时候,不能再复原的,这一点区别于Semaphore
,Semaphore
是可以通过release
操作恢复信号量的。CountDownLatch使用原理
使用原理
await()
方法,这样主线程的操作就会在这个方法上阻塞,直到其他线程完成各自的任务,count值为0,停止阻塞,主线程继续执行。使用模板
public class CountDownLatchModule {
//线程数
private static int N = 10;
// 单位:min
private static int countDownLatchTimeout = 5;
public static void main(String[] args) {
//创建CountDownLatch并设置计数值,该count值可以根据线程数的需要设置
CountDownLatch countDownLatch = new CountDownLatch(N);
//创建线程池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i {
try {
System.out.println(Thread.currentThread().getName() + " do something!");
} catch (Exception e) {
System.out.println("Exception: do something exception");
} finally {
//该线程执行完毕-1
countDownLatch.countDown();
}
});
}
System.out.println("main thread do something-1");
try {
countDownLatch.await(countDownLatchTimeout, TimeUnit.MINUTES);
} catch (InterruptedException e) {
System.out.println("Exception: await interrupted exception");
} finally {
System.out.println("countDownLatch: " + countDownLatch.toString());
}
System.out.println("main thread do something-2");
//若需要停止线程池可关闭;
// cachedThreadPool.shutdown();
}
main thread do something-1
pool-1-thread-1 do something!
pool-1-thread-2 do something!
pool-1-thread-3 do something!
pool-1-thread-5 do something!
pool-1-thread-6 do something!
pool-1-thread-7 do something!
pool-1-thread-8 do something!
pool-1-thread-4 do something!
pool-1-thread-9 do something!
pool-1-thread-10 do something!
countDownLatch: java.util.concurrent.CountDownLatch@76fb509a[Count = 0]
main thread do something-2
CountDownLatch常用方法
public void await() throws InterruptedException
:调用await()
方法的线程会被挂起,等待直到count
值为0
再继续执行。public boolean await(long timeout, TimeUnit unit) throws InterruptedException
:同await()
,若等待timeout
时长后,count
值还是没有变为0,不再等待,继续执行。时间单位如下常用的毫秒、天、小时、微秒、分钟、纳秒、秒。
public void countDown()
: count值递减1.public long getCount()
:获取当前count值。public String toString()
:重写了toString()方法,多打印了count值,具体参考源码。CountDownLatch使用场景
countDown()
方法进行递减count值
,再在主线程中使用await()
方法等待任务执行完成,主线程继续执行。CountDownLatch源码
构造方法源码
/**
* Constructs a {@code CountDownLatch} initialized with the given count.
*
* @param count the number of times {@link #countDown} must be invoked
* before threads can pass through {@link #await}
* @throws IllegalArgumentException if {@code count} is negative
*/
public CountDownLatch(int count) {
if (count
toString()方法源码
/**
* Returns a string identifying this latch, as well as its state.
* The state, in brackets, includes the String {@code "Count ="}
* followed by the current count.
*
* @return a string identifying this latch, as well as its state
*/
public String toString() {
return super.toString() + "[Count = " + sync.getCount() + "]";
}
CountDownLatch示例
作为线程启动信号
public class CountDownLatchTest {
/**
* a start signal that prevents any worker from proceeding
* until the driver is ready for them to proceed;
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(10);
for (int i = 0; i
do something else 1
do something else 2
do work!
do work!
do work!
do work!
do work!
do work!
do work!
do work!
do work!
do work!
wait for all to finsh
do something else 1
和do something else 2
。因为startSignal.countDown();
完后,count才为0,子线程才能打印。startSignal.await();
是在子线程内,所有子线程都等待startSignal.countDown()
执行后才能打印do work!
。doneSignal.await();
等待所有子线程执行后,每次都doneSignal.countDown()
,最后count为0,主线程才执行打印wait for all to finsh
。作为线程等待完成信号
public class CountDownLatchTest2 {
/**
* a completion signal that allows the driver to wait
* until all workers have completed.
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
CountDownLatch doneSignal = new CountDownLatch(5);
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i
do something else 1
do work!
i = 0, java.util.concurrent.CountDownLatch@128abd43[Count = 4]
do work!
i = 1, java.util.concurrent.CountDownLatch@128abd43[Count = 3]
do work!
i = 2, java.util.concurrent.CountDownLatch@128abd43[Count = 2]
do work!
i = 3, java.util.concurrent.CountDownLatch@128abd43[Count = 1]
do work!
i = 4, java.util.concurrent.CountDownLatch@128abd43[Count = 0]
===========================count: 0
do something else 2
do work!
i = 5, java.util.concurrent.CountDownLatch@128abd43[Count = 0]
do work!
i = 6, java.util.concurrent.CountDownLatch@128abd43[Count = 0]
do work!
i = 7, java.util.concurrent.CountDownLatch@128abd43[Count = 0]
do work!
i = 8, java.util.concurrent.CountDownLatch@128abd43[Count = 0]
do work!
i = 9, java.util.concurrent.CountDownLatch@128abd43[Count = 0]
do something else 2
信息,因为CountDownLatch数值为5。
上一篇:Python装饰器
文章标题:Java—CountDownLatch使用详解
文章链接:http://soscw.com/index.php/essay/42615.html