1. CountDownLatch无法归零,而导致主线程一直冗在那里
2. 已超出指定的等待时间
3. 其他某个线程中断当前线程
解决
1,。CountDownLatch无法归零,而导致主线程一直冗在那里
@ 在写程序的时候,代码正确,能归零
@ 为了防止出现异常,将countDown放到finally里面,都会进行执行
1 @Override 2 public void run() { 3 try { 4 function1();//执行代码 5 } catch (Exception e) { 6 //异常处理 7 e.printStackTrace(); 8 } 9 finally { 10 countDownLatch.countDown(); 11 } 12 // function1(); 13 }
2. 已超出指定的等待时间
CountDownLatch实例的await(),归避长时间阻塞线程的风险,任何多线程应用程序都有死锁风险
改用CountDownLatch实例的await(long timeout, TimeUnit unit),设定超时时间,
如:CountDownLatch.await(20,TimeUnit.SECONDS);
1 try { 2 //conutDownLatch.await(); 3 conutDownLatch.await(20,TimeUnit.SECONDS); 4 System.out.println("执行线程结束"); 5 } catch (InterruptedException e) { 6 e.printStackTrace(); 7 System.out.println("执行线程异常"); 8 }
1 public boolean await(long timeout, TimeUnit unit) 2 throws InterruptedException
在利用 countDownLatch时,有时报 线程池满了,例如:在开两个线程开两个线程调用两个方法,在计算最后合并数据的步骤中
两个线程调用两个不同的方法时,使用countdownlatch 计数器等待三个方法全部执行完成 合并数据,其中方法1是调用接口,接口出错,导致此方法1没有完成。
由于: 方法1调用异常后,没有处理异常导致不会执行线程关闭步骤(两个线程合并,线程关闭写在第二个方法里)
就像这样的场景导致线上service执行线程阻塞,接口调用次数累计导致dubbo线程满了
所以要将countDown放到finally里面,而且指定的等待时间await(long timeout, TimeUnit unit)
例子:
1 public static void main(String[] args) { 2 ExecutorService executorService =Executors.newFixedThreadPool(2); 3 CountDownLatch cdl = new CountDownLatch(2); 4 executorService.execute(new Runnable() { 5 @Override 6 public void run() { 7 try { 8 function1(); 9 } catch (Exception e) { 10 //异常处理 11 e.printStackTrace(); 12 } 13 finally { 14 cdl.countDown(); 15 } 16 // function1(); 17 } 18 }); 19 20 executorService.execute(new Runnable() { 21 @Override 22 public void run() { 23 function2(); 24 cdl.countDown(); 25 } 26 }); 27 28 29 30 try { 31 // cdl.await(); 32 cdl.await(20,TimeUnit.SECONDS); 33 System.out.println("二个执行线程结束"); 34 } catch (InterruptedException e) { 35 e.printStackTrace(); 36 System.out.println("执行线程异常"); 37 } 38 finally { 39 executorService.shutdown(); 40 System.out.println("执行线程关闭"); 41 } 42 43 44 } 45 46 private static void function1(){ 47 int i = 1/0; 48 System.out.println("方法一"); 49 } 50 51 private static void function2(){ 52 System.out.println("方法二"); 53 }
API中当调用await时候,调用线程处于等待挂起状态,直至count变成0再继续。
其大体原理如下:
地址: https://blog.csdn.net/u010144805/article/details/79259024
https://blog.csdn.net/u010598327/article/details/82083038