Java FixedThreadPool与CachedThreadPool:两个邪恶中的较小者
我有一个程序,可以生成执行一系列任务的线程(~5-150)。最初,我使用了Java FixedThreadPool与CachedThreadPool:两个邪恶中的较小者,java,multithreading,threadpool,executorservice,java.util.concurrent,Java,Multithreading,Threadpool,Executorservice,Java.util.concurrent,我有一个程序,可以生成执行一系列任务的线程(~5-150)。最初,我使用了FixedThreadPool,因为我认为它们更适合长寿命的任务,而且我对多线程的了解非常有限,我认为线程的平均寿命(几分钟)“长寿命” 但是,我最近添加了生成额外线程的功能,这样做会使我超出设置的线程限制。在这种情况下,猜测并增加我可以允许的线程数,或者切换到CachedThreadPool以便我没有浪费的线程,这会更好吗 初步尝试这两种方法,似乎没有什么不同,因此我倾向于使用CachedThreadPool以避免浪费。
FixedThreadPool
,因为我认为它们更适合长寿命的任务,而且我对多线程的了解非常有限,我认为线程的平均寿命(几分钟)“长寿命”
但是,我最近添加了生成额外线程的功能,这样做会使我超出设置的线程限制。在这种情况下,猜测并增加我可以允许的线程数,或者切换到CachedThreadPool
以便我没有浪费的线程,这会更好吗
初步尝试这两种方法,似乎没有什么不同,因此我倾向于使用
CachedThreadPool
以避免浪费。然而,线程的生命周期是否意味着我应该选择一个FixedThreadPool
,只处理未使用的线程?使这些额外的线程看起来没有被浪费,但我希望得到澄清。缓存线程池正是您在这种情况下应该使用的,因为对于长时间运行的线程使用缓存线程池不会产生负面后果。java文档中关于CachedThreadPool适用于短任务的注释仅表明它们特别适用于此类情况,而不是它们不能或不应该用于涉及长时间运行任务的任务
更详细地说,和都由相同的线程池实现(至少在开放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>());
}
publicstaticexecutorservice newFixedThreadPool(int-nThreads){
返回新的ThreadPoolExecutor(第n个线程,第n个线程,
0L,时间单位为毫秒,
新建LinkedBlockingQueue());
}
公共静态执行器服务newCachedThreadPool(){
返回新的ThreadPoolExecutor(0,Integer.MAX_值,
60升,时间单位。秒,
新建SynchronousQueue());
}
当您确实希望使用固定数量的线程时,FixedThreadPool确实有其优势,因为这样您就可以向executor服务提交任意数量的任务,同时知道线程数量将保持在您指定的级别。如果明确希望增加线程数,那么这不是合适的选择
但是,这并不意味着CachedThreadPool可能存在的一个问题是限制并发运行的线程数。CachedThreadPool不会为您限制这些线程,因此您可能需要编写自己的代码,以确保不会运行太多线程。这实际上取决于应用程序的设计以及任务如何提交给executor服务。在高负载的应用程序中,
FixedThreadPool
和CachedThreadPool
都是有害因素
CachedThreadPool
比FixedThreadPool
如果您的应用程序是高负载的,并且要求低延迟,由于以下缺点,最好将这两个选项都去掉
CachedThreadPool
在创建线程时失控FixedThreadPool不会出现这个问题,它是用2+n线程创建的,其中n当然是合理的低,因为使用硬件和操作系统资源来管理无论如何都不能运行的线程,开销要小得多。有时没有更好的选择,您可以只有一个CPU核心,但是如果您运行的服务器上的每个用户请求都会触发一个线程来处理请求,那么就没有其他合理的选择了,特别是如果您计划在扩大用户基础后扩展服务器的话。@mFeinstein如果一个人在pos中,怎么可能没有选择呢