我们有一个方案,其中提交给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的动态的更多信息,请观看here。该文档的主要注意事项如下:
  • 如果正在运行的线程数少于corePoolSize,则执行程序始终喜欢添加新线程,而不是排队。
  • 如果正在运行corePoolSize或更多线程,则执行程序总是更喜欢对请求进行排队,而不是添加新线程。
  • 如果无法将请求排队,将创建一个新线程,除非该线程超过了maximumPoolSize,在这种情况下,该任务将被拒绝。

  • 编辑
    如果您希望增加核心池的大小,则可以使用 setCorePoolSize(int corePoolSize) 。如果增加corepoolsize,则如有需要,将启动新线程以执行所有排队的任务。

    09-05 13:20