1. 现象描述
开发过程中本地调试一个程序,这个程序是:A线程调用B线程 (A、B线程都是异步调用,使用的是同一个线程池),在A线程中需要阻塞,等待B线程执行完毕拿到返回值。
这个程序本地调试没有任何问题,放到线上就程序卡死
2. 问题分析
经过反复测试,只有当A线程同一时间调用数量过多时,才会出现这种情况,因此,我们看下线程池配置
可以看到核心线程数是16 并且队列大小是无限大(Integer最大值)
当同时请求数是16个或超过16个时,A
把核心线程全部占用,同时A
需要创建一个新线程B
,但是由于现在核心线程数已经全部占用,那么jvm把开启新线程B这个任务放到线程池的队列中(A B
是同一个线程池),等到A
结束释放线程才能够开启新线程的任务,但是A线程
的结束时需要创建出B
线程,
因此造成A
、B
相互等待的情况
3. 解决方案
- A B分别使用不同的线程池
- 考虑提高核心线程数 或 降低队列大小到合适数值
- 使用CountDownLatch等JUC工具包限制同时并发数