Executors.newCachedThreadPool() vs Executors.newFixedThreadPool()
newCachedThreadPool()
vs. newFixedThreadPool()
我什么时候应该使用其中一个?在资源利用方面,哪种策略更好?
newCachedThreadPool()
vs. newFixedThreadPool()
我什么时候应该使用其中一个?在资源利用方面,哪种策略更好?
我认为文档很好地解释了这两个函数的区别和用法:
创建一个线程池,该线程池重用对共享的未绑定队列运行的固定数量的线程。在任何时候,nThreads 线程最多都是活动的处理任务。如果在所有线程都处于活动状态时提交了其他任务,则这些任务将在队列中等待,直到线程可用。如果任何线程在关闭之前由于执行过程中的故障而终止,则如果需要执行后续任务,将有一个新线程取而代之。池中的线程将一直存在,直到它被显式关闭。
创建一个线程池,该线程池根据需要创建新线程,但在以前构造的线程可用时将重用这些线程。这些池通常会提高执行许多短期异步任务的程序的性能。要执行的调用将重用以前构造的线程(如果可用)。如果没有可用的现有线程,将创建一个新线程并将其添加到池中。六十秒未使用的线程将终止并从缓存中删除。因此,长时间保持空闲状态的池不会消耗任何资源。请注意,可以使用 ThreadPoolExecutor 构造函数创建具有相似属性但详细信息不同的池(例如,超时参数)。
就资源而言,将保持所有线程运行,直到它们被显式终止。在“未使用”线程“中,将终止六十秒并从缓存中删除。newFixedThreadPool
newCachedThreadPool
鉴于此,资源消耗将在很大程度上取决于这种情况。例如,如果您有大量长时间运行的任务,我会建议.至于 ,文档说“这些池通常会提高执行许多短期异步任务的程序的性能”。FixedThreadPool
CachedThreadPool
为了完成其他答案,我想引用Joshua Bloch撰写的《Effective Java, 2nd Edition》,第10章,第68项:
“为特定应用程序选择执行器服务可能很棘手。如果你正在编写一个小程序,或者一个负载较轻的服务器,使用Experators.new- CachedThreadPool通常是一个不错的选择,因为它不需要配置,并且通常“做正确的事情”。但是,对于负载繁重的生产服务器来说,缓存线程池不是一个好的选择!
在缓存的线程池中,提交的任务不会排队,而是立即移交给线程执行。如果没有可用的线程,则会创建一个新线程。如果服务器负载如此之重,以至于其所有CPU都被充分利用,并且更多的任务到达,那么将创建更多的线程,这只会使事情变得更糟。
因此,在负载很重的生产服务器中,最好使用 Executors.newFixedThreadPool,它为您提供了一个具有固定线程数的池,或者直接使用 ThreadPoolExecutor 类,以获得最大程度的控制。"