ExecutorService固定池挂起在单个任务上

时间:2013-06-01 06:52:11

标签: java multithreading threadpool executorservice

我的代码有一个用ExecutorService固定线程池实现的线程池。 池执行的大多数任务都很短,但有时会有一个任务长时间运行,大约20-30秒。 运行此任务时,不会执行新任务,只有在长时间运行的任务完成时才会恢复。

将池设置为20,这样就不会出现问题,因为我只需要运行2个线程即可重新创建,首先是长时间运行的线程,第二个是卡住的。

我一直在讨论为什么它被卡住了然后我从newFixedThreadPool()切换到newCachedThreadPool()并且瓶颈被释放了。这是我做过的唯一改变。

这种行为有意义吗? 代码似乎运行正常所以我想我会保留更改,据我所知,如果你运行很多简短的任务,最好使用缓存线程池,但我想知道为什么固定池会挂起并且在那里一种解决方法吗?

此外,从固定切换到缓存有什么可能是副作用(如果有的话)?

感谢。

1 个答案:

答案 0 :(得分:0)

可能的结果是更多线程将同时运行,因为 newCachedThreadPool()允许运行Integer.MAX_VALUE线程计数。

如果不查看代码,很难猜测副作用。

但是,正如我想的那样,如果通过增加线程数来解决问题,那么你很有可能锁定。

例如,您有4个资源A,B,C,D。 还有4个任务:

1)短的TaskA需要资源A
2)短任务B需要资源B
3)短TaskC需要资源C
4)长TaskD需要资源A和D

所以在一个时刻我们会有下一个情况:

Thread1: TaskA await for resource A
Thread2: TaskD has A and D and running

TaskB wait in Queue
TaskC wait in Queue

当您使用无限的线程数更改pull to pull,或者使用许多允许的线程更改固定线程池时:

Thread1: TaskA await for resource A
Thread2: TaskD has A and D and running
Thread3: TaskB has resource B
Thread4: TaskC has resource C

因此,其中一个线程被另一个线程阻塞,但你无法看到,因为所有其他任务都是在没有锁定的情况下执行的。