CachedThreadPool正是您应根据情况使用的,因为长时间运行线程不使用CachedThreadPool。Java文档中有关CachedThreadPools适用于短期任务的评论仅表明它们特别适合此类情况,而不是它们不能或不应用于涉及长时间运行任务的任务。
为了进一步阐述,Executors.newCachedThreadPool和Executors.newFixedThreadPool都由相同的线程池实现(至少在开放的JDK中)支持,只是具有不同的参数。区别只是它们的线程最小值,最大值,线程终止时间和队列类型。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
当您确实想使用固定数量的线程时,FixedThreadPool确实具有其优势,因为从那时起,您可以向执行程序服务提交任意数量的任务,同时知道线程数将保持在指定的级别。如果您明确希望增加线程数,那么这是不合适的选择。
但是,这确实意味着CachedThreadPool可能存在的一个问题是限制同时运行的线程数。CachedThreadPool不会为您限制它们,因此您可能需要编写自己的代码以确保您不会运行太多线程。这实际上取决于应用程序的设计以及如何将任务提交给执行者服务。