限制Executor(Java)中的线程数

时间:2016-02-07 16:33:29

标签: java multithreading executorservice threadpoolexecutor

如何限制Executor中执行的线程数?例如,在下面的代码中:

            executor = Executors.newFixedThreadPool(this.noOfThreads);
            for (int i = 0; i < sections.size(); i++) {
                DomNode section = sections.get(i);
                // Retrieve the url of the subsection
                String subsectionUrl = section.getNodeValue();

                if(i != 0 && (i % noOfThreadsPerSection == 0)) {
                    // Add section threads to the executor
                    executor.execute(new BrowseSection(filter, webClient, subsectionUrl));
                } else {
                    executor.shutdown();
                    try {
                        executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
                    } catch (InterruptedException e) {
                        // We should normally never get here
                    }
                }
            }

当调用executor.execute()时,如果线程池充满正在运行的线程会发生什么?

上面的代码不检查线程是否仍在执行程序中运行,而是检查已启动的线程数。

3 个答案:

答案 0 :(得分:2)

无论有没有做任何事情,池都会创建固定数量的线程。它不会根据您的使用方式而改变。

您的作业将传递到队列,线程池将从队列中获取任务。当池不是全部忙时,几乎在添加任务后就会从队列中取出任务。当您有更多任务时,队列会变长。

在Java 8中,它避免为每个项目创建任务,而是将工作分解为多个部分。这样,它比以天真的方式使用ExecutorService更有效。

在Java 8中你会写。

sections.parallelStream()
        .map(s -> s.getNodeValue())
        .forEach(s -> new BrowseSection(filter, webClient, s).run());

无需启动线程池并再次将其关闭等等。等待所有任务完成。

您可以通过在命令行上设置来更改ForkJoinPool.commonPool()的大小

-Djava.util.concurrent.ForkJoinPool.common.parallelism=N

如果在此类加载之前执行此操作,也可以实际设置。

答案 1 :(得分:1)

从java文档中,newFixedThreadPool有一个无界的队列,因此所有其他线程都会等待:

  

创建一个重用固定数量的线程的线程池   关闭共享的无界队列。在任何时候,最多nThreads线程   将是主动处理任务。如果提交了其他任务   当所有线程都处于活动状态时,它们将在队列中等待直到a   线程可用。如果任何线程由于故障期间终止而终止   在关机之前执行,如果需要,新的将取代它   执行后续任务。池中的线程将一直存在   它是明确关闭的。

答案 2 :(得分:1)

Executors & ExecutorService 不提供用于控制任务队列大小的API,默认情况下这是无限制的。

如果您的任务花费的时间间隔更短,则使用ExecutorService即可。

首选ThreadPoolExecutor,它可以更好地控制TaskQueueSize,拒绝处理机制。

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

您可以使用以下API

动态控制线程池大小
setCorePoolSize(newLimit)

有关详细信息,请查看这些SE问题:

Dynamic Thread Pool