记一次多线程下CountDownLatch 引发的死锁问题
这阵子开发环境一个dubbo服务发生一个假死现象:
dubbo服务正常,日志持续打印pong日志,但是所有请求都返回超时或者通道关闭。
如下:
1、Caused by: org.apache.dubbo.remoting.TimeoutException: Waiting server-side response timeout by scan timer
2、Caused by: org.apache.dubbo.remoting.RemotingException: message can not send, because channel is closed
排查最后发现问题片段类似下面,在CountDownLatch内再开多个子线程,子线程内再使用countDownLatch,导致问题出现。
猜测是因为死锁导致dubbo的线程耗尽,但是并发请求几个也会出现这个问题,匪夷所思。
还有一个就是countDownLatch,我一直以为以这个对象为锁,我在每个Thread内都有新建一个countDownLatch对象,那正常逻辑来说也是不会出现死锁状况的。
demo简单,就是这么个场景,有大佬知道什么原因的吗?
样例代码:
public class Test {
public static void main(String[] args) throws InterruptedException {
CountDownLatch count = new CountDownLatch(2);
// 第一个线程
new Thread(()->{
childThread();
count.countDown();
}).start();
// 第二个线程
new Thread(()->{
childThread();
count.countDown();
}).start();
// 等待两个任务完结
count.await();
System.out.println("结束!");
}
/**
* 子任务
*/
private static void childThread() {
try{
CountDownLatch count = new CountDownLatch(3);
// 第一个线程
new Thread(()->{
System.out.println("最小的任务");
count.countDown();
}).start();
// 第二个线程
new Thread(()->{
System.out.println("最小的任务");
count.countDown();
}).start();
// 第三个线程
new Thread(()->{
System.out.println("最小的任务");
count.countDown();
}).start();
// 等待两个任务完结
count.await();
System.out.println("子任务结束!");
}catch (Exception e){
e.printStackTrace();
}
}
}