Keep-alive 如何与 ThreadPoolExecutor 一起工作?

70

作为我之前发布的一个question的延续,我正在尝试在我的代码库中使用ThreadPoolExecutor。即使我反复尝试从Java API文档中理解,我仍然无法清楚地理解构造函数中传递keepAliveTime参数的功能/目的。希望有人能用一些好的工作示例来解释给我。

Java文档摘录:

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue)

keepAliveTime - 当线程数大于核心数时,多余的空闲线程等待新任务的最长时间,超过此时间将终止。


2
仅作为术语上的指点,你在两个地方使用了“implement”这个词,我认为你只是想说“使用”。你并不打算通过编写自己实现该 API 的代码来 实现 ThreadPoolExecutor - 你只是要创建一个 ThreadPoolExecutor,并想知道它会如何行动,对吗? - Jon Skeet
是的,你说得对。我只是想表达这是我代码库中一种新的实现方式。 - Gnanam
但它并不是 ThreadPoolExecutor 的一个实现。如果您在 Stack Overflow 上可以适当地使用术语,这将非常有帮助。 - Jon Skeet
3个回答

105
假设您的核心大小为5,最大大小为15。出于某种原因,您的池忙碌起来,使用了所有可用的15个线程。最终,您没有更多的工作要做 - 因此一些线程完成其最后一个任务后会变为空闲状态。因此,这10个线程被允许死亡。
但是,为了避免它们被过快地杀死,您可以指定保持活动时间。因此,如果您将1指定为“keepAliveTime”值,并将“TimeUnit.MINUTE”指定为“unit”值,则每个线程在执行完任务后将等待一分钟以查看是否有更多的工作要做。如果它仍然没有得到任何更多的工作,它将让自己完成,直到池中只剩下5个线程 - 即池的“核心”。

4
如果我理解正确的话,“keepAliveTime”仅在线程池中的线程数超过核心大小时才被使用/生效。当线程池中的线程数低于核心大小时,这是不适用的。 - Gnanam
3
杀死线程的目的与最初创建线程池的目的相同--避免浪费不必要的资源。 - Marko Topolnik
6
@Gnanam - 这样线程就可以执行另一个任务,从而节省创建新线程的开销。 - Martin James
2
@Gnanam:这确实是我的理解。这并不意味着它一定是正确的,但至少是一致的 :) - Jon Skeet
2
@Prabhath:假设你所说的“等待网络调用”是指正在进行网络调用并阻塞等待其完成,那么不,它不是空闲的 - 它是被阻塞的。如果它是空闲的,它可以执行另一个任务。如果它被阻塞了,就不能执行其他任务。 - Jon Skeet
显示剩余7条评论

6

以下是来自Javadoc的更多描述:

<dt>Keep-alive times</dt>
 *
 * <dd>If the pool currently has more than corePoolSize threads,
 * excess threads will be terminated if they have been idle for more
 * than the keepAliveTime (see {@link
 * ThreadPoolExecutor#getKeepAliveTime}). This provides a means of
 * reducing resource consumption when the pool is not being actively
 * used. If the pool becomes more active later, new threads will be
 * constructed. This parameter can also be changed dynamically
 * using method {@link ThreadPoolExecutor#setKeepAliveTime}. Using
 * a value of <tt>Long.MAX_VALUE</tt> {@link TimeUnit#NANOSECONDS}
 * effectively disables idle threads from ever terminating prior
 * to shut down.
 * </dd>
 *

本质上,这仅允许您控制空闲池中剩余线程的数量。如果您将其设置得太小(针对您正在执行的操作),那么您将创建过多的线程。如果您将其设置得太大,则会消耗您不需要的内存/线程。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接