ExecutorService 应该是静态的和全局的吗?

2022-09-03 07:56:28

我想在整个应用程序中使用相同的线程池。为此,我可以使静态和全局,以便我可以在需要时调用以获取。ExecutorServiceThreadUtil.executorServiceExecutorService

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

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

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


答案 1

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

至于你的第二个查询,我不认为它有任何问题。文档的第一句话说newCachedThreadPool

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

由于您不知道将创建多少个线程,因此这是最合乎逻辑的选择。

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


答案 2

我不会让它直接全球化。至少将其包装在一个类中,以便您可以轻松地使用多个池。当您需要多种具有不同优先级的作业/作业时,拥有线程池非常有用。只需将较少的线程放在其他池和/或较低优先级的线程中(通过覆盖线程工厂)。有关示例,请参阅 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/ddt/blob/master/Core/src/main/web/common/threads.jsp 等操作创建一个实用程序jsp / servlet