2016-02-07 42 views
2

如何限制在Executor中执行的线程数?例如,在代码波纹管:速率限制执行程序(Java)中的线程数

  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

,数量线程受限于this.noOfThreads。它永远不会比这更大 –

+0

noOfThreads是在给定时间运行的一批线程的大小(假设有更多部分)。但是,如果节的数量大于this.noOfThreads,并且线程仍未完成,那么执行if时会发生什么情况?执行程序是否等待某些线程完成或不完成? – Sebi

+0

您可以阅读更多关于ThreadPoolExecutor的信息:https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html –

回答

2

该池创建固定数量的线程,无论是否有任何要执行的操作。它不会根据你如何使用它而改变。

您的作业被传递给队列,线程池从队列中获取任务。当池不忙时,任务几乎一旦添加就会从队列中拉出。当你有更多的任务时,队列变长。

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

在Java 8中,你会写。

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

没有必要重新启动线程池并将其关闭等。等待所有任务完成。

您可以通过在命令行

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

您还可以设置这个务实的前提是你这个类加载之前做到这一点的设置改变ForkJoinPool.commonPool()的大小。

+1

不应该将最后一个参数subsectionUrl替换为s。 – Sebi

+1

@Sebi确实,我现在已经修好了。 –

+0

而且,Executor如何发挥作用?此代码为s中的每个条目创建一个线程,我想限制该线程,为应用程序使用的线程数设置一个上限。 – Sebi

1

从Java文档的newFixedThreadPool具有无界队列等所有其他线程将等待:

创建一个可重用操作 关闭不受限制的队列线程固定数量的线程池。在任何时候,最多nThreads线程 将被激活的处理任务。如果在所有线程处于活动状态时提交了其他任务 ,则他们将在队列中等待,直到 线程可用。如果任何线程在关闭之前执行 期间因失败而终止,则在需要 执行后续任务时将取代它。池中的线程将一直存在,直到 它被明确关闭。

1

Executors & ExecutorService没有提供API来控制任务队列的大小,默认情况下是无限的。

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

优选ThreadPoolExecutor,它提供了对TaskQueueSize,Rejection Handling机制的更好控制。

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

您可以通过以下API

setCorePoolSize(newLimit) 

看一看这些SE的问题更多细节动态控制线程池的大小:

Dynamic Thread Pool

在你的榜样