CountDownLatch的作用很简单,就是一个或者一组线程在开始执行操作之前,必须要等到其他线程执行完才可以。我们举一个例子来说明,在考试的时候,老师必须要等到所有人交了试卷才可以走。此时老师就相当于等待线程,而学生就好比是执行的线程。
注意:java中还有一个同步工具类叫做CyclicBarrier(多个线程间相互等待),他的作用和CountDownLatch类似。同样是等待其他线程都完成了,才可以进行下一步操作。我们再举一个例子,在打王者的时候,在开局前所有人都必须要加载到100%才可以进入。否则所有玩家间都需要相互等待。
简单看一下二者的区别:
CountDownLatch: 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行 。
CyclicBarrier : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
关键点其实就在于那N个线程
(1)CountDownLatch里面N个线程就好比参加考试的学生,学生做完了试卷就可以走了,不用等待其他的学生是否完成,但老师需要等到所有学生都交卷了才能离开。
(2)CyclicBarrier 里面N个线程就好比王者荣耀里所有的游戏玩家,一个游戏玩家加载到100%还不可以,必须要等到所有的游戏玩家都加载到100%才可以开局。
现在应该理解CountDownLatch的含义了吧,下面我们使用一个代码案例来解释。
import java.util.concurrent.CountDownLatch;
/**
* @task
* @Author: JXS
* @DateTime: 2019/11/19 22:51
* @Description: TODO
* @Version v1.0
*/
public class CountDownLatchTest {
static CountDownLatch countDownLatch = new CountDownLatch(5);
public static void main(String[] args) {
System.out.println("全班同学开始考试:一共5个学生");
for (int i = 0; i < 5; i++) {
new Thread(() -> {
// 学生好比子线程
System.out.println("学生" + Thread.currentThread().getName() + "开始考试");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("学生" + Thread.currentThread().getName() + "交卷并离开考场,countDownLatch减1");
countDownLatch.countDown();
}).start();
}
try {
System.out.println("老师" + Thread.currentThread().getName() + "开始监考!");
countDownLatch.await();
System.out.println(" 所有学生都已交卷,老师" + Thread.currentThread().getName() + "开始亲点试卷离开考场!,在此之前,只要一个学生没交," +
"countDownLatch不为0,不能离开考场");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("老师清点试卷,在此之前,只要一个学生没交,"
+ "countDownLatch不为0,不能离开考场");
}
}
运行结果:
全班同学开始考试:一共5个学生
老师main开始监考!
学生Thread-0开始考试
学生Thread-1开始考试
学生Thread-2开始考试
学生Thread-3开始考试
学生Thread-4开始考试
学生Thread-0交卷并离开考场,countDownLatch减1
学生Thread-1交卷并离开考场,countDownLatch减1
学生Thread-4交卷并离开考场,countDownLatch减1
学生Thread-3交卷并离开考场,countDownLatch减1
学生Thread-2交卷并离开考场,countDownLatch减1
所有学生都已交卷,老师main开始亲点试卷离开考场!,在此之前,只要一个学生没交,countDownLatch不为0,不能离开考场
老师清点试卷,在此之前,只要一个学生没交,countDownLatch不为0,不能离开考场
主线程需要等到所有子线程运行结束,自己才能被唤醒开始执行
在上面我们看到,CountDownLatch主要使用countDown方法进行减1操作,使用await方法进行等到操作。我们进入到源码中看看。本源码基于jdk1.8。特在此说明。
2.源码分析
未完待续,源码解析。。。