2013-01-14 122 views
3

我有一個程序,它並行運行(全天)任務(任務中沒有I/O要執行),所以我用Executors.newFixedThreadPool(poolSize)來實現它。Java線程池大小和availableProcessors()

最初,我將poolSize設置爲Runtime.getRuntime().availableProcessors(),但由於在同一臺PC上運行了其他進程(32個內核),所以我有點擔心要使用所有可用的內核。

特別是我有十個其他JVM運行相同的程序(在不同的輸入數據上),所以我有點擔心在可用內核之間切換線程可能會有很多開銷,下整體計算。

我該如何決定每個程序/ JVM池的大小?

此外,在我的電腦中,還有其他進程一直在運行(防病毒,備份等)。我是否也應該考慮到這些?

+0

你只擔心自己的計算機上運行此程序?如果是這樣,爲什麼不嘗試一個特定的選擇,查看您的CPU使用情況,並相應地進行調整。也許你可以在這裏發表你的發現。 – BlackVegetable

+4

需要特別注意的是,從Runtime.availableProcessors()''的Javadocs中注意到 - 「在特定的虛擬機調用期間,該值可能會發生變化。」換句話說,這種方法不會做你認爲它的做法。相反,可以通過屬性文件或命令行參數來配置線程池的大小。 – Brian

回答

1

任何建議將取決於您的具體情況。在32個內核上的10個JVM每個會建議3個線程(忽略垃圾收集線程,定時器任務等)。

您還有其他任務正在運行。調度程序將確保它們正在運行,但它們是否必須響應?比JVM響應更快?如果您正在運行Linux/Unix,那麼您還可以使用優先級(通過nice)確保特定進程不會佔用CPU。

最後,您正在運行10個JVM。會導致分頁?如果是這樣,那將會很慢,並且爲了避免消耗太多內存,您最好不要使用更少的JVM。

只要確保您的關鍵變量已公開並可配置,並測量各種情況以找到最佳關鍵變量。

1

我應該如何決定每個程序/ JVM池的大小?

你想要的線程數將使你接近99%的利用率,沒有更多。

平衡工作的最簡單方法是讓進程運行一次,同時處理多個文件並僅使用一個線程池。如果您需要通過命令行啓動文件,您可以將其設置爲服務處理。

如果由於某種原因這是不可能的,您將需要猜測線程池應該縮減多少。嘗試運行一個進程並查看利用率。如果有人說40%,那麼我懷疑有10個程序被過度使用了400%。即您可能會將池大小減少4倍。

0

不幸的是,這是一件很難知道的事情,因爲程序通常不知道同一個盒子上還有什麼或者可能會發生什麼。

「簡單」的出路是使池大小可配置。這允許控制程序/框的用戶決定要分配給程序的線程數量(大概是使用他們對盒子一般工作負載的瞭解)。

更復雜的解決方案是嘗試以編程方式確定框的當前工作負載並從中適當地選擇池大小。此解決方案的功效取決於您可以如何準確確定工作負載,並可能隨着時間的推移而進行調整。