使用executorService提交(submit)线程任务时,若任务执行过程中抛出未被捕获的RuntimeException或error时,会造成这条线程终止吗? 比如若原来线程池中有五条线程,抛出这样的异常时就变成了4条,以此类推,最后这个线程池中就没有线程了。是这样吗?求大神解答
ps:
就是之前自己实验了一下new了一个只有1个线程的线程池,然后不断的向线程池中提交任务,然后在任务中抛出一个RunTimeException,若是线程池中线程如问题所描述的那样会终止,那么线程池不应该再接受任务,但结果确是 线程池仍然可以不断的接受任务。所以,有些不太确定才上来求助。源码确实还没看。
=============================最后====================================
感谢各位的热心帮助,任务中抛出未被捕获的异常确实不会造成线程池的线程消失。线程池对此做了保护机制。之前产生这样错觉的原因是,我写了一个批量下载支付宝提现文件的模块,为了提升效率用到了线程池。但我发现随着时间的推移,线程池中的可用线程越来越少,直至没有了。就好像线程池中的线程消失了一样。今天发现原因了,原来是因为我没有设置HttpClient的超时时间导致的,httpClient默认的read response超时时间好像是24小时,所以遇到有问题的下载连接这个线程就被长时间占用了。其实只要加上超时时间就好了,超时抛出异常就好了。
![](https://pic4.zhimg.com/4c50b651c90fc797352422cf7342a7db_b.jpg)
最后吐槽一下我们的开发环境,我们是在内网开发啊~~~ 没网啊~~~ 打出的版本要在外网测试啊~~ 所以开发需要联网程序的时候,我就呵呵了~ 不能debug,出现问题根据自己的想象,在内网改好了,在通过公司流程考到外网测试,有时候改几行代码,等到拷到外网半天就过去了~~~~~
ps:
就是之前自己实验了一下new了一个只有1个线程的线程池,然后不断的向线程池中提交任务,然后在任务中抛出一个RunTimeException,若是线程池中线程如问题所描述的那样会终止,那么线程池不应该再接受任务,但结果确是 线程池仍然可以不断的接受任务。所以,有些不太确定才上来求助。源码确实还没看。
=============================最后====================================
感谢各位的热心帮助,任务中抛出未被捕获的异常确实不会造成线程池的线程消失。线程池对此做了保护机制。之前产生这样错觉的原因是,我写了一个批量下载支付宝提现文件的模块,为了提升效率用到了线程池。但我发现随着时间的推移,线程池中的可用线程越来越少,直至没有了。就好像线程池中的线程消失了一样。今天发现原因了,原来是因为我没有设置HttpClient的超时时间导致的,httpClient默认的read response超时时间好像是24小时,所以遇到有问题的下载连接这个线程就被长时间占用了。其实只要加上超时时间就好了,超时抛出异常就好了。
![](https://pic4.zhimg.com/4c50b651c90fc797352422cf7342a7db_b.jpg)
最后吐槽一下我们的开发环境,我们是在内网开发啊~~~ 没网啊~~~ 打出的版本要在外网测试啊~~ 所以开发需要联网程序的时候,我就呵呵了~ 不能debug,出现问题根据自己的想象,在内网改好了,在通过公司流程考到外网测试,有时候改几行代码,等到拷到外网半天就过去了~~~~~
关注者
45
被浏览
6286
7 个回答
知乎“温赵轮”三大软狗之一。
![知乎用户](https://pic1.zhimg.com/da8e974dc_xs.jpg)
知乎用户
上源代码:
看到try/catch没,finally里面有个afterExecute来处理异常的。这说明,线程池使用了try/catch对你的任务(task)进行保护,你的任务有异常,线程池的线程不会崩溃,而是记录一下,接着处理下一个任务。
![](https://pic1.zhimg.com/2db40143402537c466db0e95d486d7a4_b.jpg)
java/机器学习/期货
守
首先,这类的问题在Stack OverFlow上问更加合适,而不应该是知乎。
不过既然你诚心诚意的问了,我那就大发慈悲的告诉你吧
![](https://pic1.zhimg.com/f86fedffee24d6540ea86ab1e873e85c_b.jpg)
就这样,你终止的只是当前线程的任务而已,跟是否销毁线程无关。
![知乎用户](https://pic1.zhimg.com/da8e974dc_xs.jpg)
知乎用户
最近在学习Java线程池,忍不住答一发。
先说我的结论:
发生异常时,使用submit方法不会影响线程池,但使用execute方法会造成该线程销毁并创建新的线程。
========================我是分割线===========================
使用submit方法时,异常会在FutureTask的run方法被捕获,并记录下来:
![](https://pic3.zhimg.com/v2-16958aead61eb9b512fd8cb1d11d5f6a_b.png)
在主线程调用get方法时,异常会被抛出来:
![](https://pic2.zhimg.com/v2-805686e6cf2c4bc96591428932bc7221_b.jpg)
所以不会影响线程池。
使用execute方法时,虽然ThreadPoolExecutor的runWorker方法捕获到异常,但又重新抛出了:
![](https://pic1.zhimg.com/v2-2766d4ea750923c9c6db6ede7e18cd80_b.jpg)
导致了该线程的销毁并创建新线程:
![](https://pic2.zhimg.com/v2-fa2266aa49d156c322f52b6a08c1a551_b.png)
以上。
![知乎用户](https://pic1.zhimg.com/da8e974dc_xs.jpg)
知乎用户
源码看不看不重要,建议详细看一下 jdk 自带线程池的文档。
jdk 自带线程池中线程何时销毁是由线程池的多个参数综合决定的,所以用户提交的线程中是否抛出了异常对线程池中线程的销毁是没有影响的。
如果用户提交的线程抛出了异常会退出用户线程的 run 方法,执行线程是否需要销毁由线程池决定。