技术问答-15

CountDownLatch

CountDownLatch 也是并发包里的一个类
我理解的它的做用是监控线程执行状态,如果在主线程中启动了三个线程 A B C
我想等A B C 都执行完之后 才执行主线程后边的某段代码 我们当然可以用join 把线程join到我们的主线程中 按顺序执行 但是这就成了单线程了 这个时候我们就需要CountDownLatch
1. countDown
一个线程执行完之后 调用countDown CountDownLatch的总数标记就会-1(当然不是仅仅-1 这么简单 里边设计很多复杂内容 但是可以理解为-1 )
2. await
主线程调用await 会等待CountDownLatch的标记变为0(不是变为0这么简单 这里暂且可以理解成变为0 因为变为0意思就是A B C 线程都执行了countDown )
2. await(long timeout, TimeUnit unit)
与await 类似 只是加了时间参数 如果在这个时间没有执行完A B C 那么就失败

package test;import java.util.concurrent.CountDownLatch;import java.util.concurrent.TimeUnit;public class Test {public static void main(String[] args) {
		CountDownLatch cdl = new CountDownLatch(3);new MyThread(cdl).start();new MyThread(cdl).start();new MyThread(cdl).start();
		System.out.println("等待子线程执行完.....");try {
			cdl.await();} catch (InterruptedException e) {
			e.printStackTrace();}
		System.out.println("子线程执行完了 执行主线程任务.....");}}class MyThread extends Thread {
	CountDownLatch cdl;public MyThread(CountDownLatch cdl) {this.cdl = cdl;}@Overridepublic void run() {// 执行任务for (int i = 0; i < 4; i++) {try {
				System.out.println(this.getName() + "线程执行任务");
				TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {
				e.printStackTrace();}}// 任务执行完成之后 执行countDown 让标记-1
		System.out.println(this.getName() + "执行结束");
		cdl.countDown();}}

输出结果为:

Thread-0线程执行任务
Thread-2线程执行任务
Thread-1线程执行任务
等待子线程执行完.....Thread-1线程执行任务
Thread-2线程执行任务
Thread-0线程执行任务
Thread-2线程执行任务
Thread-1线程执行任务
Thread-0线程执行任务
Thread-1线程执行任务
Thread-2线程执行任务
Thread-0线程执行任务
Thread-2执行结束
Thread-0执行结束
Thread-1执行结束
子线程执行完了 执行主线程任务.....

我们可以看到 子线程还是以多线程的方式执行,但是主线程是在等子线程全部执行完之后才执行的主线程任务

这里的关键是需要共享一个CountDownLatch 用了一个有参的构造函数 传递给没个线程

我对她的理解就是这样 欢迎不出 质疑

上一篇:CountDownLatch源码


下一篇:使用Zookeeper实现分布式锁