1 CountDownLatch介绍
当某项工作需要由若干项子任务并行地完成,并且只有在所有的子任务结束之后(正常结束或者异常结束),当前主任务才能进入下一阶段,CountDownLatch工具将是非常好用的工具,并且其所提供的操作方法还是线程安全的。
CountDownLatch(Count Down Latch,直译为倒计数门阀),它的作用就与其名字所表达的意思一样,是指有一个门阀在等待着倒计数,直到计数器为0的时候才能打开,当然我们可以在门阀等待打开的时候指定超时时间。
2 入门程序:等待所有子任务结束
主线程中开辟了三个线程,主线程必须等待三个线程执行完成(可能依赖三个线程的执行结果),才可以继续向下执行:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* @author wyaoyao
* @date 2021/4/20 11:09
*/
public class CountDownLatchDemo1 {
public static void main(String[] args) {
// 定义CountDownLatch,计数器数量为子任务的个数为3
CountDownLatch countDownLatch = new CountDownLatch(3);
// 构建三个线程
for (int i = 1; i <= 3; i++){
int finalI = i;
new Thread(()->{
try {
// 模拟线程执行
TimeUnit.SECONDS.sleep(finalI);
System.out.println(Thread.currentThread().getName() + " 执行结束");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
// 每个线程执行结束,使计数器减减
countDownLatch.countDown();
}
},"T-" + i).start();
}
// 主线程需要等待三个子线程,全部执行结束才会执行向下执行
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("三个子线程全部执行结束,主线程可以继续执行了");
}
}
最后的输出:
T-1 执行结束
T-2 执行结束
T-3 执行结束
三个子线程全部执行结束,主线程可以继续执行了
主(父)线程(main)将会被阻塞,直到所有的子线程完成了工作(计数器变为0)。
3 CountDownLatch的总结
CountDownLatch具体使用如下:
- CountDownLatch的构造非常简单,需要给定一个不能小于0的int数字。
- countDown()方法,该方法的主要作用是使得构造CountDownLatch指定的count计数器减一。如果此时CountDownLatch中 的计数器已经是0,这种情况下如果再次调用countDown()方法,则会被忽略,也就是说count的值最小只能为0。
- await()方法会使得当前的调用线程进入阻塞状态,直到count为0,当然其他线程可以将当前线程中断。同样,当count的值为0的时候,调用await方法将会立即返回,当前线程将不再被阻塞。
- await(long timeout, TimeUnit unit)是一个具备超时能力的阻塞方法,当时间达到给定的值以后,计数器count的值若还大于0,则当前线程会退出阻塞。
- getCount()方法,该方法将返回CountDownLatch当前的计数器数值,该返回值的最小值为0。