ExecutorService应该是静态的还是全局的

我想在整个应用程序中使用相同的线程池。 为此,我可以使ExecutorService静态和全局的,这样我就可以在需要时调用ThreadUtil.executorService来获取ExecutorService

 public class ThreadUtil { public static final ExecutorService executorService = Executors.newCachedThreadPool(); } 

可以像这样实例化多个线程池吗?

另外,我的应用程序是TCP服务器。 如果我不知道池应该有多大,可以简单地使用newCachedThreadPool吗?

当在程序中的任何地方使用具有相同属性的实例时,将其声明为静态和最终而不是每次重新创建实例是合乎逻辑的,但我个人会选择Singleton模式而不是直接授予公共访问权限。实例。

至于你的第二个查询,我没有看到任何问题。 newCachedThreadPool文档的第一句话说

创建一个根据需要创建新线程的线程池

因为您不知道将创建多少个线程,所以这是最合理的选择。

请注意, newCachedThreadPool将在可用时重新使用旧线程以提高性能。

我不会直接全球化。 至少将它包装在一个类中,这样您就可以轻松使用多个池。 当您需要多种具有不同优先级的作业/作业时,拥有一个线程池池非常有用。 只需在其他池和/或较低优先级的线程中放置较少的线程(通过过度使用线程工厂)。 有关示例,请参阅https://github.com/tgkprog/ddt/tree/master/DdtUtils/src/main/java/org/s2n/ddt/util/threads

用法:

 //setup PoolOptions options = new PoolOptions(); options.setCoreThreads(2); options.setMaxThreads(33); DdtPools.initPool("poolA", options); Do1 p = null; // Offer a job: job = new YourJob(); DdtPools.offer("poolA", job); 

也不要使用缓存池,因为它可以根据需要增长,而不是TCP可以无限制地阻止。 您想使用受控池。 如果需要,可以重新初始化上述库(增加线程数,同时允许当前作业在旧池被丢弃到GC之前处理)。

可以为https://github.com/tgkprog/ddt/blob/master/Core/src/main/web/common/poolEnd.jsp和https://github.com/tgkprog等操作制作实用程序jsp / servlet /ddt/blob/master/Core/src/main/web/common/threads.jsp

如果您的应用程序只有ExecutorServivce,则可以继续使用静态全局。

newCachedThreadPool()newFixedThreadPool()都不提供对Callable/Runnable任务队列的控制。 它们使用无界队列 ,这可能导致系统性能下降。

我更喜欢使用ThreadPoolExecutor ,它可以更好地控制各种参数,如队列大小,拒绝处理程序,线程工厂等。

 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, RejectedExecutionHandler handler) 

要么

 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) 

有关详细信息,请参阅以下post:

FixedThreadPool vs CachedThreadPool:两个邪恶中较小的一个