CountDownLatch是并发包下的倒计时协调器。
用法很简单,特别类似Thread.join()方法,但是比join更灵活。
代码如下:
1 package com.moon.forum.controller; 2 3 import java.util.concurrent.CountDownLatch; 4 import java.util.concurrent.TimeUnit; 5 6 public class Test { 7 public static void main(String[] args) { 8 try { 9 //倒计时初始值为5 10 final CountDownLatch count = new CountDownLatch(5); 11 for (int i = 0; i < 5; i++) { 12 new Thread() { 13 public void run() { 14 try { 15 Thread.sleep(6000); 16 }catch(Exception e1){ 17 System.out.println("出错了"); 18 } 19 System.out.println("我是线程" + Thread.currentThread().getName() + "执行完毕"); 20 21 //每次减一 22 count.countDown(); 23 } 24 }.start(); 25 } 26 System.out.println("开始等待"); 27 28 //主线程等待 29 boolean timeout = count.await(5, TimeUnit.SECONDS); 30 System.out.println("over"+timeout); 31 }catch(Exception e){ 32 System.out.println("出错了"); 33 } 34 } 35 }
上面代码超级好懂吧。就是主线程里开启5个子线程。然后每个子线程调用下countDown方法,就当与倒计时减1,当倒计时器为0,主线程就接着往下执行。
但是这样如果有子线程一直堵塞,则容易造成主线程也没办法执行下去,所以通常用 await(5, TimeUnit.SECONDS) ,他表示我只能多长时间,过时不候!霸气不?
但是这个也会有一个隐含的事实,即使是超过最长等待时间,主线程不管子线程有没有执行完,他自己继续执行,但是子线程却还是会继续执行的。这时候就会出现主线程和子线程并发的情况。
所以大家在业务中用这个的时候,如果在主线程中因为子线程超时而做出补偿逻辑的时候,就要注意了:因为子线程迟早会执行完。