介绍
CountDownLatch(线程计数器)是一个同步辅助类,创建CountDownLatch时需要传入一个int
类型的参数,表示需要等待完成的线程数,被等待的线程在创建时需传入CountDownLatch的实例,在适当的时候调用countDown()
表示一个被等待线程执行完毕,等待线程使用同一CountDownLatch实例的await()
方法去等待。当所有的被等待线程都执行完毕,就会唤醒所有阻塞在await()
方法上的线程。
常用方法列表
//构造一个用指定计数的 CountDownLatch。
CountDownLatch(int count)
// 使当前线程在计数器倒计数至零之前一直等待,除非线程被中断。
void await()
// 使当前线程在计数器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。
boolean await(long timeout, TimeUnit unit)
// 递减计数器的计数,如果计数到达零,则释放所有等待的线程。
void countDown()
// 返回当前计数。
long getCount()
应用示例
public class CountDownLatchTest {
private static int NUM = 3;
//被等待线程
static class MyTask implements Runnable{
private CountDownLatch countDownLatch;
private String name;
public MyTask(CountDownLatch countDownLatch, String name) {
this.countDownLatch = countDownLatch;
this.name = name;
}
@Override
public void run() {
System.out.println(name+":开始执行");
//模拟任务的执行
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+":执行结束");
//计数器减一
countDownLatch.countDown();
}
}
//被等待线程
static class MyWaitingTask implements Runnable{
private CountDownLatch countDownLatch;
private String name;
public MyWaitingTask(CountDownLatch countDownLatch, String name) {
this.countDownLatch = countDownLatch;
this.name = name;
}
@Override
public void run() {
System.out.println(name+":开始执行");
try {
//在此等待
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+":执行结束");
}
}
public static void main(String[] args) {
//初始化计数器
CountDownLatch countDownLatch = new CountDownLatch(NUM);
ExecutorService pool = Executors.newFixedThreadPool(NUM);
ExecutorService waitingPool = Executors.newFixedThreadPool(NUM);
for(int i =0;i<NUM;i++){
waitingPool.execute(new MyWaitingTask(countDownLatch,"等待线程"+i));
}
for(int i =0;i<NUM;i++){
pool.execute(new MyTask(countDownLatch,"被等待线程"+i));
}
waitingPool.shutdown();
pool.shutdown();
}
}
运行结果
等待线程0:开始执行
等待线程2:开始执行
被等待线程0:开始执行
被等待线程1:开始执行
等待线程1:开始执行
被等待线程2:开始执行
被等待线程0:执行结束
被等待线程1:执行结束
被等待线程2:执行结束
等待线程0:执行结束
等待线程1:执行结束
等待线程2:执行结束
总结
- CountDownLatch作为一个调整线程执行顺序的工具类,可以很方便的去实现一组线程等待另一组线程执行完毕后执行,需等待的线程数就是构造CountDownLatch对象时传入的数量,如果其中一个被等待的线程在调用CountDownLatch的
countDown()
方法前异常退出,将导致之后等待的线程无限期等待。