2016-02-07 82 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

在你的榜樣