简体   繁体   English

Java Executor Service 在应用程序启动时启动线程

[英]Java Executor Service Start Threads when Application Launches

When my application launches, a executor service (using Executors.newFixedThreadPool(maxThreadNum) in java.util.concurrent) object is created.当我的应用程序启动时,会创建一个执行程序服务(在 java.util.concurrent 中使用 Executors.newFixedThreadPool(maxThreadNum))对象。 When requests come, the executor service will creates threads to handle them.当请求到来时,执行器服务将创建线程来处理它们。

Because it takes time to create threads at run time, I want to make threads available when launching application, so that when requests come, it would take less time to process.因为在运行时创建线程需要时间,所以我想在启动应用程序时让线程可用,这样当请求到来时,处理时间会更少。

What I did is following:我所做的如下:

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 " );
        }
    });
}

It will creates 200 threads in the executorService pool when application launches.当应用程序启动时,它将在 executorService 池中创建 200 个线程。

Just wonder is this a correct way of creating threads when application starts?只是想知道这是在应用程序启动时创建线程的正确方法吗? Or is there a better way of doing it?或者有更好的方法吗?

You are missing shutdown() .It is very important to shutdown the Executor service once the operation is completed.您缺少shutdown() 。操作完成后关闭 Executor 服务非常重要。 So have try,catch and Finally block所以有try,catch and Finally block

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

If you can use a ThreadPoolExecutor directly rather than an ExecutorService from Executors 1 , then there's perhaps a more standard/supported way to start all the core threads immediately.如果您可以直接使用ThreadPoolExecutor而不是来自Executors 1ExecutorService ,那么可能有一种更标准/受支持的方法来立即启动所有核心线程。

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

The above uses prestartAllCoreThreads() .以上使用prestartAllCoreThreads()

Note that, currently, the implementation of Executors.newFixedThreadPool(int) creates a ThreadPoolExecutor in the exact same manner as above.请注意,目前Executors.newFixedThreadPool(int)的实现以与上述完全相同的方式创建了一个ThreadPoolExecutor This means you could technically cast the ExecutorService returned by the factory method to a ThreadPoolExecutor .这意味着您可以在技术上将工厂方法返回的ExecutorService转换为ThreadPoolExecutor There's nothing in the documentation that guarantees it will be a ThreadPoolExecutor , however.但是,文档中没有任何内容可以保证它是ThreadPoolExecutor


1. ThreadPoolExecutor implements ExecutorService but provides more functionality. 1. ThreadPoolExecutor实现了ExecutorService但提供了更多的功能。 Also, many of the factory methods in Executors either returns a ThreadPoolExecutor directly or a wrapper that delegates to one.此外, Executors许多工厂方法要么直接返回一个ThreadPoolExecutor要么返回一个委托给一个的包装器。 Some, like newWorkStealingPool , use the ForkJoinPool .有些,比如newWorkStealingPool ,使用ForkJoinPool Again, the return types of these factory methods are implementation details so don't rely too much on it.同样,这些工厂方法的返回类型是实现细节,所以不要过分依赖它。

The number of threads which could run parallel depends on your processor core.可以并行运行的线程数取决于您的处理器内核。 Unless you have 200 cores it would be pretty useless to make a thread pool of 200.除非您有 200 个内核,否则创建 200 个线程池将毫无用处。

A great way to find out how many processors cores you have is:找出您拥有多少处理器内核的好方法是:

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

Moreover the overhead which develops during creating a new thread and executing it is unavoidable, so unless the task is heavily computed it would not be worth to create a new single thread for this task.此外,在创建新线程和执行它期间产生的开销是不可避免的,因此除非任务被大量计算,否则为该任务创建新的单线程是不值得的。

But after all your code is total fine so far.但毕竟你的代码到目前为止完全没问题。

Your code is totally fine if it works for your scenario.如果它适用于您的场景,您的代码完全没问题。 Since we don't know your use case, only you can answer your question with enough tests and benchmark.由于我们不知道您的用例,因此只有您可以通过足够的测试和基准来回答您的问题。

However, do take note that the ThreadPool will reclaim idle threads after some time.但是,请注意 ThreadPool 会在一段时间后回收空闲线程。 That may bite you if you don't pay attention to it.如果你不注意它,它可能会咬你。

Just wonder is this a correct way of creating threads when application starts?只是想知道这是在应用程序启动时创建线程的正确方法吗?

Yes.是的。 That's a correct way of creating threads.这是创建线程的正确方法。

Or is there a better way of doing it?或者有更好的方法吗?

Maybe.也许。 Under some workloads you might want to use a Thread pool with a variable number of threads (unlike the one created by newFixedThreadPool ) - one that removes from the pool threads that have been idle for some time.在某些工作负载下,您可能希望使用具有可变线程数的线程池(与newFixedThreadPool创建的线程不同) - 从池中删除闲置一段时间的线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM