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

Gna*_*nam 41 java multithreading keep-alive

继续我发布的问题,我正在尝试在我的代码库中使用ThreadPoolExecutor.即使在多次尝试从Java API doc中理解之后,我也无法清楚地理解keepAliveTime在构造函数中传递的参数背后的功能/目的.希望有人能用一些好的工作实例来解释我.

摘自Java doc:

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue)
Run Code Online (Sandbox Code Playgroud)

keepAliveTime- 当线程数大于核心数时,这是多余空闲线程在终止之前等待新任务的最长时间.

Jon*_*eet 68

假设您的核心大小为5,最大大小为15.由于某种原因,您的池会变忙,并使用所有15个可用线程.最终你没有工作要做 - 所以你的一些线程在完成最后的任务时就会空闲.因此,其中10个线程被允许死亡.

但是,为了避免它们被快速杀死,您可以指定保持活动时间.所以,如果你指定1作为keepAliveTime值,并TimeUnit.MINUTEunit值,每个线程将等待一分钟便完成了执行任务,看看是否有更多的工作要做了.如果它还没有得到任何更多的工作,它将自己完成,直到池中只有5个线程 - 池的"核心".

  • @Gnanam - 这样线程就可以执行另一个任务,从而节省了创建新线程的开销. (5认同)
  • 如果我理解正确的话,当池中的线程超过核心大小时,"keepAliveTime"仅用于"有效".当池中的线程低于核心大小时,这不适用*. (2认同)
  • 杀死线程的重点与首先拥有线程池的点相同 - 不浪费不必要的资源. (2认同)
  • @Gnanam:这当然也是我的理解。这并不是说它*必然*正确,但至少是一致的:) (2认同)
  • @Prabhath:假设“等待网络调用”是指它正在进行网络调用并阻塞以等待它完成,那么不,它不是空闲的 - 它是阻塞的。如果它是空闲的,它可以被赋予另一个任务。如果它被阻止,它不能。 (2认同)
  • @Gnanam 它也可以应用于核心线程。来自文档:`默认情况下,保持活动策略仅适用于超过 corePoolSize 的线程。但是方法 {@link #allowCoreThreadTimeOut(boolean)} 也可用于将此超时策略应用于核心线程,只要 keepAliveTime 值不为零即可。` (2认同)
  • 如果`keepAliveTime` 为0,我还对池中的线程如何存储/删除感兴趣。答案是[这里](https://docs.oracle.com/javase/7/docs/api/java/util/ concurrent/ThreadPoolExecutor.html#setKeepAliveTime(long,%20java.util.concurrent.TimeUnit)):时间值为零将导致多余的线程在执行任务后立即终止。[newFixedThreadPool](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool(int))中使用0 (2认同)

Fra*_* IV 7

以下是 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>
 *
Run Code Online (Sandbox Code Playgroud)

本质上,这只是允许您控制空闲池中剩余的线程数量。如果你让它太小(对于你正在做的事情),你将创建太多线程。如果你把它设置得太大,你将消耗不需要的内存/线程。