我希望這不是過於寬泛;我的問題是「如何設計一個不能自鎖死鎖的多線程池服務?」。線程池死鎖:針對或檢測
我擁有一個Web服務,它可以在單個用戶請求中扇出100個線程,以低延遲執行數據聚合。有很多ExecutorServices在我的服務中包裹着固定線程池,我需要幫助解決這個可能造成死鎖的有趣方式。
我有一個線程池A
它用於保持線程發出網絡請求,另一個線程池B
用於保存其「擁有」線程;商業邏輯的聚合位可能會引發少量請求。此外,當B
中的線程偶爾將工作位提交給線程池B
時,可以通過聚合3個更簡單的子聚合來完成聚合。
這種模式是問題所在。讓我們考慮提交給B
的請求類型x
,這導致請求x'
的另外請求被提交給B
。我們也考慮B
是50個線程的固定線程池。當x
類型的50個請求同時進入時,B
中的所有線程都用於處理這些請求。他們都將x1
提交到B
,它們位於等待線程的隊列中。然後,所有請求的所有處理都處於死鎖狀態60秒,直到超時命中並且x
請求所有返回異常。
事情我已經考慮/嘗試:
- 調整數。可以連接的最大用戶數是50,
B
中的線程數是100.防止出現問題,但是當另一個開發人員在一年內調整不相關數字時似乎會破壞黑客,而且沒有人能夠弄清楚爲什麼我們每週在負載下鎖定一次。我想在設計中解決這個問題。 B
提交扇出工作到B'
,一個新的線程池。不起作用,因爲此扇出可能會執行多個步驟(我是否創建了B''
,B'''
,...?)B
沒有最大線程數。可能可以接受,看起來很危險。- 另一種模式(更多callbackish?)線程不提交併等待同一工作單元;而是他們提交工作並向 「運行後」池中提交「回調」。這樣,任何東西都無法在自己的游泳池中等待。有沒有先例,這是一個好主意嗎?
- 將所有線程池合併在一起並刪除最大值?
我認爲這是一個很好的問題。你應該嘗試更多的事件導向(或者你提到的回調)。你可以嘗試threadpools,event-queues,[actors](http://akka.io/),甚至可以用非常棒的[lmax ringbuffer disruptor](https://github.com/LMAX-Exchange/disruptor)短期任務。我建議你使用基礎庫來完成這個任務,比如[RxJava](https://github.com/ReactiveX/RxJava)或者[Reactor](http:// spring。IO /博客/ 2013/05/13 /反應器-A-基礎換異步應用 - 上的-JVM /)。只是避免線程,你的要求指向別的地方。 –