5

我试图理解为 Java 5 的 ThreadPoolExecutor 指定单独的核心和最大池大小的要点。我的理解是,线程数只有在队列满后才会增加,这似乎有点晚了(至少对于更大的队列)。

是不是我很乐意为任务分配更多的线程,在这种情况下我可能只是增加核心池的大小;或者我不太愿意这样做,在这种情况下我应该有一个更大的队列?什么是单独的核心和最大池大小有用的场景?

4

2 回答 2

4

这里有一个讨论

该池旨在在 corePoolSize 的正常负载下工作(除非使用预启动,否则它将加速到该负载)。当发生过载情况时(定义为挂起/正在进行的任务多于工作人员),我们使用队列作为缓冲区 - 期望在不久的将来恢复正常工作负载。如果我们担心过度过载,那么我们可以使用有界队列,即“如果队列已满,则添加更多工作人员,直至达到 maxPoolSize”。如果我们使用无界队列,我们​​会说我们不期望(或者不关心)过度过载。

目的是平衡处理预期工作负载的能力,即使在瞬态过载的情况下,也不会创建过多的线程,也不会产生过多的线程流失(即 create-work-die-create)。

于 2011-09-21T03:33:27.387 回答
2

不同之处在于,如果您低于核心池大小,则每个新任务都会创建一个新线程,而不管池中的空闲线程如何。只有当您已经达到核心池大小但仍低于最大值时,队列已满时才会增加线程数。

一个完美的例子是当你有一个你不知道它会有多少并发负载的系统时(例如一个网络服务器)。此功能允许您指定一组核心线程,可能基于您的机器拥有的核心数量,但允许比您预期的更多负载。

如果您的 I/O 负载比您预期的要多,并且池中的线程花费大量时间阻塞,这将特别有用。在这种情况下,您的队列可以很容易地填满,而不会产生大量并发负载,并且可以通过添加几个新线程来服务更多并发请求来轻松修复它。

于 2011-09-21T03:16:39.863 回答