应用程序启动时的Java执行程序服务启动线程

时间:2018-10-17 09:11:34

标签: java executorservice java-threads

启动我的应用程序时,将创建执行程序服务(使用java.util.concurrent中的Executors.newFixedThreadPool(maxThreadNum))。当请求到来时,执行程序服务将创建线程来处理它们。

由于在运行时创建线程需要花费时间,因此我想在启动应用程序时使线程可用,以便在请求到来时处理时间减少。

我所做的是:

executorService = Executors.newFixedThreadPool(200);
for (int i=0; i<200; i++) {
    executorService.execute(new Runnable() {
        @Override
        public void run() {
            System.out.println("Start thread in pool " );
        }
    });
}

当应用程序启动时,它将在executorService池中创建200个线程。

只想知道这是应用程序启动时创建线程的正确方法吗? 还是有更好的方法呢?

5 个答案:

答案 0 :(得分:3)

您缺少shutdown()。完成操作后,关闭Executor服务非常重要。 try,catch and Finally block

try{ executorService.execute(...); }catach(Exception e){ ... }finally{ executorService.shutdown(); //Mandatory }

答案 1 :(得分:2)

如果您可以直接使用ThreadPoolExecutor而不是ExecutorService 1 中的Executors,那么可能有更标准/受支持的方式来启动所有立即成为核心线程。

int nThreads = 200;
ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads, 
        0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
executor.prestartAllCoreThreads();

以上使用prestartAllCoreThreads()

请注意,目前,Executors.newFixedThreadPool(int)的实现以与上述完全相同的方式创建了ThreadPoolExecutor。这意味着您可以从技术上将工厂方法返回的ExecutorService强制转换为ThreadPoolExecutor。但是,文档中没有任何内容可以保证 ThreadPoolExecutor


1。 ThreadPoolExecutor实现了ExecutorService,但提供了更多功能。同样,Executors中的许多工厂方法要么直接返回ThreadPoolExecutor,要么返回委托给它的包装器。有些newWorkStealingPool等使用ForkJoinPool。同样,这些工厂方法的返回类型是实现细节,因此请不要过于依赖它。

答案 2 :(得分:1)

可以并行运行的线程数取决于您的处理器内核。除非您有200个内核,否则创建200个线程池将毫无用处。

找出拥有多少处理器核心的好方法是:

int cores = Runtime.getRuntime().availableProcessors();

此外,在创建新线程并执行该线程时所产生的开销是不可避免的,因此,除非对该任务进行大量计算,否则不值得为此任务创建新的单线程。

但是到目前为止,您的代码毕竟还不错。

答案 3 :(得分:1)

如果您的代码适用于您的情况,则完全可以。由于我们不知道您的用例,因此只有您可以使用足够的测试和基准来回答您的问题。

但是,请注意,ThreadPool将在一段时间后回收空闲线程。如果您不注意它,那可能会咬你。

答案 4 :(得分:0)

  

请问这是应用程序创建线程的正确方法吗?   开始吗?

是的。这是创建线程的正确方法。

  

还是有更好的方法呢?

也许。在某些工作负载下,您可能希望使用具有可变数量线程的线程池(与newFixedThreadPool创建的线程池不同)-一种线程池从池中移出已闲置了一段时间的线程。