2012-07-11 43 views
0

在我們的多線程Java應用程序,我們使用的是LinkedBlockingDeque單獨的實例爲每個線程,線程假設(C1,C2,... C200)LinkedBlockingDeque.take() - 在multipe線程單獨的實例

線程T1 & T2接收來自套接字&的數據將對象添加到特定消費者的Q之間的c1到c200之間。

無限循環運行()的內部,它調用LinkedBlockingDeque.take()

在負載運行的javae.exe本身的CPU使用率是40%。當我們總結系統中的其他進程時,整體CPU使用率達到90%。

通過使用JavaVisualVM運行()佔用了過多的CPU,我們懷疑LinkedBlockingDeque.take()

像thread.wait因此試圖替代品,並通知和的Thread.Sleep(0),但沒有改變。

之所以每個消費者具有分離的Q是兩個原因, 1.there 2.如果我們轉儲單Q,所述SEACH時間對所有REQ可能是從T1或T2 消費者C1多於一個的請求c1到c200會更多,並且搜索條件將會延長。 3.and讓消費者有單獨的Q處理thier請求

設法降低CPU使用率,需要你輸入...

SD

回答

0
  1. 做分析和作確保隊列方法需要相當多的CPU時間。您的郵件處理過程如此簡單,與將隊列放入/取出隊列相比,處理起來如此簡單? 每秒處理多少條消息?有多少個CPU?如果每個CPU每秒處理少於100K條消息,那麼很可能原因不是對隊列的訪問,而是消息處理本身。

  2. 加入LinkedBlockingDeque會創建一個幫助對象的實例。我懷疑,每個新消息都是從堆中分配的,所以每個消息都有2個創建。嘗試使用預先分配的消息池和循環緩衝區。

  3. 200線程太多了。這意味着,許多上下文切換。嘗試使用actor庫和線程池,例如,https://github.com/rfqu/df4j(是的,它是我的)。

  4. 檢查http://code.google.com/p/disruptor/是否符合您的需求。

+0

感謝您的回覆,我們會根據您的要求處理郵件。最多200條消息/秒。 2個CPU。如果消費者沒有消息,則調用LinkedBlockingDeque.take()來阻塞,直到獲得消息。 2)該消息包含特定消費者的唯一標識符。對於其他兩點,現在還不知道。還沒有看到。 – user1517020 2012-07-11 10:46:47

+0

對於如此低的消息速率,調整通信策略不太可能產生任何效果。但是,我會嘗試以下變體:單個消息隊列,1或2個消費者線程從隊列中讀取,消費者用方法void processMessage(Message m)表示爲對象(不是線程)。消費者線程將消息放入由消息內容選擇的消費者對象中。使用2個線程時,需要額外的預防措施不要同時訪問同一個消費者對象(演員模型的經典用例):例如每個消費者都有額外的隊列。 – 2012-07-11 11:58:11

+0

謝謝。使用單個共享隊列,每個消費者將處理數據。這種類型的設計可以達到的最大消息速率是多少。 – user1517020 2012-07-20 12:51:52