2017-02-28 13 views
3

傳遞給ThreadPoolExecutor/ScheduledThreadPoolExecutor的推薦corePoolSize是什麼?傳遞給ThreadPoolExecutor/ScheduledThreadPoolExecutor的推薦corePoolSize是什麼?

Runtime.getRuntime().availableProcessors()Runtime.getRuntime().availableProcessors() * 2

從一個角度來看,我希望CPU(所有內核)能夠100%利用,但儘可能少用線程,以便儘快完成並且不會有太多的處罰在上下文切換。

另一方面,一些線程可能無法一直利用CPU,如等待網絡。在這種情況下,我希望生成新線程並保持所有內核繁忙。

如果有暫時的CPU過度使用,我很好。比使用不足和任務未被處理更好。

那麼如何才能實現這種線程負載平衡呢?謝謝。

+0

我想找到一種方法讓java動態地產生線程而不會導致性能問題。對於靜態解決方案,我可以設置一個數字。相關:http://stackoverflow.com/questions/1718465/optimal-number-of-threads-per-core –

回答

1

我認爲這將取決於你在做什麼。您已經暗示某些線程可能正在等待I/O。

corePoolSize是池將保留的線程數,即使閒置。我想你想設置最大池大小。

上下文切換的開銷總是在那裏,我不認爲它實際上會增加更多的線程,因爲切換通常實現爲常量切片(即時間切片的減少與可運行線程的數量成反比)。

您顯然至少需要與核心數量相同的線程來實現滿載,需要多少額外的線程取決於線程完成的速度以及I/O需要多長時間。

一種選擇是在一個大池大小的單獨步驟中執行I/O操作,以確保始終有一個I/O步驟已經完成(CompletableFuture對此很方便)。然後,在下一步中,您將使用一個單獨的ThreadPool,其池大小與一個線程完成後將從上一步中提供的核心數相同。

像這樣(未經證實):

CompletableFuture.supplyAsync(ioTask, ioExecutorWithLargePool) 
    .thenAccept(cpuBoundTask, executorWithCpuCoreSizedPool); 
1

你可以看看Amdahl's law定義核心的數量。把你的程序看作是一個單線程程序,看看你可以並行化的地方。這可以給你一個N的想法(這裏我們可以近似的核心數量,由應用程序的線程數量)。根據我的經驗,確定「最佳」線程數量的最佳方法仍然是創建多線程程序,並使用盡可能多的線程數值進行測試,並查看哪一個輸出最佳性能。 (也Optimal number of threads per core見)

1

至於除了john16384的回答是:

您的代碼Runtime.getRuntime().availableProcessors()? Runtime.getRuntime().availableProcessors() * 2可能是一個好主意,如果你的CPU支持每個CPU核心(多線程)兩個線程。

3

調整線程池的大小取決於您要在該池上執行的任務的性質。作爲一般規則,它取決於等待時間和CPU時間之間的比率以及可用的CPU數量。

的一般公式來套用的是:

Sizing Threads Pools

保持處理器在理想利用的最佳池大小:

Optimal thread-pool sizing

你可以找到更多信息Java Concurrency In Practice,部分8.2調整線程池

相關問題