我们有一个场景,提交给 ThreadPoolExecutor 的任务长时间运行。当线程池启动时,我们以核心池大小 = 5、最大池大小 = 20 和队列大小 10 来启动它。在我们的应用程序中,大约有 10 个任务被提交。大多数时候,这些任务运行几分钟/小时然后完成。然而,有一种情况是所有 5 个任务都在 I/O 上挂起。结果,我的核心池大小达到了最大值,但我的 Threadpoolexecutor 队列未满。所以额外的 5 个任务永远没有机会运行。
请建议我们如何处理这种情况?在这种情况下,较小的队列是更好的选择吗?初始化 threadPool 时最佳队列大小是多少?
另外对于挂起的任务,有什么办法可以将线程从线程池中拉出来吗?在这种情况下,至少其他任务将有机会运行。
整体情况是这样的:
core pool size = 5,
max pool size = 20 and
queue size of 10
提交了10个任务。其中有
- 5 个任务挂在 I/O 上 => 核心池大小的所有线程都被占用。因此没有空闲线程。
- 剩余 5 项任务。由于没有空闲线程且队列可容纳 10 个任务,因此将这 5 个线程排队到队列中。这些排队任务只有在队列已满或核心池中的任何线程空闲时才会执行。
因此,您的程序被挂起。
想了解更多动态ThreadPoolExecutor
watch here http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html。该文档的要点如下:
- 如果运行的线程少于 corePoolSize,则 Executor 始终倾向于添加新线程而不是排队。
- 如果 corePoolSize 或更多线程正在运行,Executor 总是更喜欢对请求进行排队而不是添加新线程。
- 如果请求无法排队,则会创建一个新线程,除非这超出了 MaximumPoolSize,在这种情况下,该任务将被拒绝。
EDIT
如果您想增加核心池大小,那么您可以使用setCorePoolSize(int corePoolSize) http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html#setCorePoolSize%28int%29。如果您增加corepoolsize
然后,如果需要,将启动新线程来执行任何排队的任务。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)