A 似乎适合您的情况,因为直接对长时间运行的线程使用一个线程不会产生负面影响。Java文档中关于CachedThreadPools适用于短期任务的评论只是表明它们特别适合这种情况,而不是它们不能用于长时间运行的任务。CachedThreadPool
a 的主要问题是,它将创建最多数量的线程,因为如果缓存中不存在未使用的线程,它将始终生成新线程。因此,如果您有长时间运行的任务,则更有可能将并发线程数增加到比所需数量更多的数量,因为这种类型的线程池不会限制并发执行的数量。对于您的用例来说,这似乎不是所描述的问题,但这是需要注意的。CachedThreadPool
Integer.MAX_VALUE
为了进一步阐述 a 和 a 之间的区别,Executors.newCachedThreadPool 和 Executors.newFixedThreadPool 都由相同的线程池实现(至少在打开的 JDK 中)通过 一个实例支持,只是具有不同的参数。区别只是它们的线程最小值,最大值,线程终止时间和队列类型。CachedThreadPool
FixedThreadPool
ThreadPoolExecutor
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>());
}
当您确实想要使用固定数量的线程时,A确实有其优势,从那时起,您可以将任意数量的任务提交给执行器服务,同时知道线程数量将保持在您指定的级别。如果显式想要增加线程数,则这不是合适的选择。FixedThreadPool
但是,这确实意味着您可能遇到的一个问题是限制并发运行的线程数。不会限制它们,因此您可能需要编写自己的代码来确保不会运行太多线程,您可以通过使用所需的行为特征实例化自己的线程来相对轻松地完成此操作。这实际上取决于应用程序的设计以及将任务提交到执行程序服务的方式。CachedThreadPool
CachedThreadPool
ThreadPoolExecutor