简介:
允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。
CountDownLatch用给定的计数初始化。 await方法阻塞,直到由于countDown()方法的调用而导致当前计数达到零,之后所有等待线程被释放,并且任何后续的await 调用立即返回。 这是一个一次性的现象 - 计数无法重置。 如果您需要重置计数的版本,请考虑使用CyclicBarrier 。
CountDownLatch是一种通用的同步工具,可用于多种用途。 一个CountDownLatch为一个计数的CountDownLatch用作一个简单的开/关锁存器,或者门:所有线程调用await在门口等待,直到被调用countDown()的线程打开。 一个CountDownLatch初始化N可以用来做一个线程等待,直到N个线程完成某项操作,或某些动作已经完成N次。
适用情况:
需要执行完所有子线程后再统一处理的情况。比如说读取数据,读取所有数据再处理接下来的事情。
CountDownLatch一个有用的属性是,它不要求调用countDown线程等待计数到达零之前继续,它只是阻止任何线程通过await ,直到所有线程可以通过。
CountDownLatch 先初始化值,一般有几个线程就初始化多少
CountDownLatch countDownLatch = new CountDownLatch(3);
阻塞主线程,调用之后主线程将被阻塞在这里,子线程继续执行,直到countDownLatch减为0
countDownLatch.await();
让countDownLatch减1。
countDownLatch.countDown()
例:晚上吃饭,要等所有人回来再开饭。
注:使用CountDownLatch 需要注意,子线程中的countDown()最好放到finnally里面,防止计数器不为0
import java.util.concurrent.CountDownLatch;
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
System.out.println("妈妈正在做饭,通知家人们回家吃饭");
CountDownLatch latch = new CountDownLatch(3);
Thread t1 = new Thread(new ThreadTest1(latch));;
Thread t2 = new Thread(new ThreadTest2(latch));
Thread t3 = new Thread(new ThreadTest3(latch));
//等待所有家人回家
System.out.println("所有家人都在回来的路上");
t1.start();
t2.start();
t3.start();
//latch.await(1,TimeUnit.SECONDS);//超时等待的情况,设置1秒为超时,第二个参数是单位
latch.await(); //模拟等待的情况,不考虑子线程的处理时间
System.out.println("开饭");
}
}
class ThreadTest1 extends Thread {
CountDownLatch lanch;
public ThreadTest1() {
}
public ThreadTest1(CountDownLatch lanch) {
this.lanch = lanch;
}
@Override
public void run() {
System.out.println("父亲刚下班,正在开车回家,预计还有30分钟到家");
lanch.countDown();
}
}
class ThreadTest2 extends Thread {
CountDownLatch lanch;
public ThreadTest2() {
}
public ThreadTest2(CountDownLatch lanch) {
this.lanch = lanch;
}
@Override
public void run() {
System.out.println("大姐正在回家的路上,预计还要15分钟");
lanch.countDown();
}
}
class ThreadTest3 extends Thread {
CountDownLatch lanch;
public ThreadTest3() {
}
public ThreadTest3(CountDownLatch lanch) {
this.lanch = lanch;
}
@Override
public void run() {
System.out.println("小弟正在路上,预计还要20分钟到家");
lanch.countDown();
}
}