2012-10-12 35 views
0

我試圖同時處理通過Web服務的一些交易(通過它的Java API),使用可調用和線程池是「線程飢餓死鎖」在這裏發生的

public class CallableTxSender implements Callable<Transaction> { 

    private Transaction transaction; 
    private Engine engine; 

    public CallableTxSender(Transaction transaction, Engine engine) { 
     this.transaction = transaction; 
     this.engine= engine; 
    } 

    @Override 
    public Transaction call() throws Exception { 
     return engine.processTx(transaction); 
    } 

} 

哪裏Engine - 是的API, Web服務調用。

我創建了一個說50個線程的池;

ExecutorService executorService = Executors.newFixedThreadPool(50); 
List<Transaction> transactions = transactionDao.getPaidTxs(); 

Engine engine= new Engine(); 
for (Transaction transaction : transactions) { 
    CallableTxSender txSender = new CallableTxSender(transaction, engine); 
    executorService.submit(txSender); 
} 

當我嘗試處理100個事務,它開始罰款第一20-30交易,那麼某個地方,這只是掛起。我不確定API是否支持同時請求,但它應該。

我想確定的是我的客戶端部分很好。你怎麼看?

編輯:我將池大小減少到10,它處理得很好。謝謝Marko從評論。 問題仍然是,是什麼讓一個池與50個併發任務掛起,而不是10個?

非常感謝

+0

它看起來像問題將是'engine.processTx(交易)'... – assylias

+0

作爲一般的建議,你幾乎肯定會在提高通過使用許多並行服務電話性能失效。我預計性能會在10個併發請求之前或之前平穩。 –

回答

1

我在您提供的代碼中看不到問題。

而不是猜測掛在哪裏我會得到一個堆棧跟蹤jstackjvisualvm,並找到掛起的線程和他們正在共享的對象的行和堆棧跟蹤。

0

如果交易不相互依賴,那麼您的代碼是確定的。爲了確保使用newCachedThreadPool而不是newFixedThreadPool。

1

當提交給執行程序服務的任務提交其他任務並等待它們完成時,會發生線程匱乏死鎖。問題中的代碼中沒有任何內容表明發生在這裏。

您的代碼的其他部分導致線程匱乏死鎖並非不可能,但您還應該考慮其他類型死鎖的可能性。


的問題仍然是,雖然,是什麼讓一個泳池,50級併發的任務掛起,而不是10?

確實無法說出來。然而,一種可能的解釋是,同時執行更多任務會增加發生特定鎖定情形的可能性。 (這個比喻是生日悖論...)

的必然結果是,減少池的大小已顯着減少死鎖的可能性,但你不能肯定你已經完全消除這個問題。在java.util.concurrent中

+0

謝謝,我編輯我的問題,將是很好,如果你可以看看 – braincell

+0

我... ...和更新我的答案。 –

+0

謝謝,我明白你的意思,但我仍然感到困惑。它無法控制API,我在每次調用時都創建了Engine的新實例。我只是想確保API部分負責「不能處理這種數量的同時事務」。 – braincell

0

ThreadPoolExecutor實現可以幫助你調整線程池的大小,工作隊列大小以及其他各種可擴展性掛鉤。 隊列大小和最大池大小可以相互交換。當所有corePoolSize線程繁忙或新建線程達到最大池大小時,新任務將等待workQueue。如果兩個工作隊列已滿,並且最大池線程都很忙,然後提交給執行新的任務將被拒絕,任務排斥的政策之一將開始發揮作用。當工作量大時,任務應該是彼此獨立的。