什么是CountDownLatch
CountDownLatch是一个同步工具类,它允许一个或多个线程等待,直到其他线程的操作执行完后再执行。如:java的main方法所在的线程要等待其他启动的线程都执行完成后再退出main方法,可以使用CountDownLatch。
CountDownLatch工作原理
CountDownLatch是通过计数器来实现等待的,初始时计数器值为线程数量,每执行完一个任务,线程计数器值减1,直到减为0,表示所有线程执行完成,等待的线程就可以执行了。
java.util.concurrent.CountDownLatch的构造方法:
public CountDownLatch(int count) {
if (count < 0)
throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
其中count即为要等待的线程数量,该值只能通过构造方法设置,没有其他方法可以改变。
主线程必须在其他线程启动后立即调用await()方法,这样可以使主线程阻塞,直到其他线程完成后,继续运行主线程。
await方法:
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
await有两个实现,其中一个带timeout参数的代表超时,超过这个时间后,如果计数器不为0则返回false。
示例代码
下面看一下使用方法:
public class TestCountDownLatch {
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(2);
new Thread(()->{
System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");
latch.countDown();
},"子线程1").start();
new Thread(()->{
System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");
latch.countDown();
},"子线程2").start();
try {
System.out.println("等待2个子线程执行完毕...");
latch.await();
System.out.println("2个子线程已经执行完毕");
System.out.println("继续执行主线程");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出结果:
等待2个子线程执行完毕...
子线程子线程1正在执行
子线程子线程2正在执行
子线程子线程1执行完毕
子线程子线程2执行完毕
2个子线程已经执行完毕
继续执行主线程