如何限制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()
时,如果线程池充满正在运行的线程会发生什么?
上面的代码不检查线程是否仍在执行程序中运行,而是检查已启动的线程数。
答案 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问题: