2012-03-22 78 views
2

我想在Java中使用線程池。但線程的數量是未知的,所以我試圖找到一個解決方案。然後發生了兩個問題:Java - 管理線程池的大小(主要增加)

  1. 我在尋找一段時間內線程池的大小增加了,但是我還是無法想出一些東西。對此有何建議?有人說Executors.newCachedThreadPool()應該可以工作,但是根據方法的定義,它表示它適用於短時線程。

  2. 如果我將線程池的大小設置爲50或100這樣的大數字,該怎麼辦?它工作正常嗎?

+0

您是否嘗試過使用JConsole監視JVM? – 2012-03-22 16:26:27

+0

@AmitBhargava不,我沒有嘗試,現在我只是在做一些研究。 – mtyurt 2012-03-22 18:13:23

回答

3
  1. 可以使用Executors.newCachedThreadPool更多的長期的任務也,但問題是,如果你有長時間運行的任務,他們正在不斷地更頻繁地比現有的任務被完成,添加線程數量將失去控制。在這種情況下,使用(更大的)固定大小的線程池並讓其他任務在隊列中等待空閒線程可能會更好。

  2. 這隻會意味着你可能會(大概)有大量的活動線程在大多數時間處於睡眠狀態(空閒狀態)。基本上要考慮的事情是

    • 你的系統可以處理多少個線程?線程和更多的一些調整系統配置)
    • 每個線程消耗的內存方面至少單個線程的堆棧大小(在Linux中,這可以是像每個線程1-8MB默認情況下,再次它可以調整ulimits和JVM的-Xss參數)
    • 至少與NPTL,應該最小或幾乎爲零睡眠線程的上下文切換懲罰,所以過多的廣告CPU使用率

話雖這麼說的術語不是「重」,它很可能是最好直接使用ThreadPoolExecutor的構造函數來得到的那種集中你想要的。

+0

在第二種解決方案中,我必須在開始時填充池嗎?因爲在大多數情況下,工作線程的數量將低於最大尺寸。 – mtyurt 2012-03-22 18:12:03

+0

我不確定我是否理解「填充」泳池的含義。 ThreadPoolExecutor具有prestartAllCoreThreads()方法,該方法啓動「corePoolSize」線程數量。否則,池將根據ThreadPoolExecutors的JavaDoc(答案中的鏈接)中記錄的條件啓動一個新線程。 – esaj 2012-03-22 18:30:10

+0

例如,我將大小設置爲50,是否必須向池中添加50個線程,或者它可以正常工作,比方說10個線程?在你說過會有很多活着但空閒的線程之後,我想知道這一點。可能它會工作,但我只想確定:) – mtyurt 2012-03-22 19:29:48

2

Executors.newCachedThreadPool()允許您根據需求創建線程。我認爲你可以從這裏開始 - 我看不到它說的是短時線程,但我敢打賭,原因是因爲你正在重新使用可用線程,使用短線程可以保持同時活動的數量線程相當低。

除非你有太多的線程在運行(你可以使用JVisualVM或JConsole進行檢查),否則我會建議堅持使用該解決方案 - 特別是因爲預期線程的數量未定義。然後分析VM並相應地調整池。

對於問題2 - 你指的是使用類似Executors.newFixedThreadPool(int)的東西嗎?如果是,請記住創建ThreadPool時定義的線程數會使線程等待 - 而不是在其中動態創建新線程的newCachedThreadPool

+0

我知道線程會等待,謝謝。我想知道在使用第二種解決方案時是否會出現問題。 – mtyurt 2012-03-22 18:10:43

+1

@mtyurt是的,你可以通過使用你的第二個解決方案(一個數十或數百個大型線程池)導致問題。如果池中的那些線程是CPU限制的(忙於做計算而不是等待存儲I/O或網絡活動),那麼[context-switching]的成本(https://en.wikipedia.org/wiki/Context_switch )可能會變得沉重和適得其反。由於適得其反,我的意思是整體績效下降,因爲越來越少的實際生產性工作得以完成。這個答案正確地指出你的任務可以排隊等待。等待意味着沒有工作,沒有上下文切換。 – 2015-05-16 01:00:14