含雪幸福

导航

 

 

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

posted on 2019-07-02 11:16  含雪幸福  阅读(803)  评论(0编辑  收藏  举报
 
/*生成博客目录的CSS*/ #uprightsideBar{ font-size:12px; font-family:Arial, Helvetica, sans-serif; text-align:left; position:fixed;/*将div的位置固定到距离top:50px,right:0px的位置,这样div就会处在最右边的位置,距离顶部50px*/ top:50px; right:0px; width: auto; height: auto; } #sideBarTab{ float:left; width:30px; border:1px solid #e5e5e5; border-right:none; text-align:center; background:#ffffff; } #sideBarContents{ float:left; overflow:auto; overflow-x:hidden;!important; width:200px; min-height:108px; max-height:460px; border:1px solid #e5e5e5; border-right:none; background:#ffffff; } #sideBarContents dl{ margin:0; padding:0; } #sideBarContents dt{ margin-top:5px; margin-left:5px; } #sideBarContents dd, dt { cursor: pointer; } #sideBarContents dd:hover, dt:hover { color:#A7995A; } #sideBarContents dd{ margin-left:20px; }