2014-04-20 56 views
0

我正在閱讀java中的重入鎖定和同步塊之間的比較。我正在瀏覽互聯網上的各種資源。我發現在同步塊中使用Reentrant鎖的一個缺點是,在前一個版本中,您必須明確使用try finally block來調用finally塊中獲取的鎖的unlock方法,因爲您的關鍵代碼段可能可能拋出異常,如果線程沒有釋放鎖,會造成很大的麻煩,而在後一種情況下,JVM本身負責在異常情況下釋放鎖。查詢關於在同步塊上重入鎖定的缺點

我不是很相信這個缺點,因爲它不是一個大問題,使用try最後,我們使用它已經block.As了很長一段時間前(流閉等)。有人可以告訴我Re-entrant鎖對同步塊的其他一些缺點嗎?

+1

有沒有任何其他缺點:一'synchronized'塊基本上是無雜波'ReentrantLock'。但這是足夠的理由:你不應該不必要地複雜你的代碼。 – assylias

回答

0

甲的ReentrantLock爲不同的使用情況下的不同的工具。雖然你可以同時使用這兩種方法來處理大多數同步問題(這就是他們所做的),但它們具有不同的優點和缺點。

花樣最多簡單:你寫同步的,就是這樣。對於現代的JVM,它合理的速度很快,但是它的缺點是它會把所有嘗試進入同步塊的線程置於保持狀態,無論它們是否真的需要。如果你經常使用同步,這可以大大降低多線程的速度,最糟糕的情況下,單線程執行速度會更快。

由於線程問題只發生在別人正在讀寫同一數據段的情況下,程序經常會遇到問題,他們理論上可能會在沒有同步的情況下運行,因爲大多數線程只是讀取,但有這個一次偶爾寫入,這會強制執行同步塊。這就是Locks的作用:你可以更好地控制你實際同步的時間。

基本的ReentrantLock允許 - 除了構造函數中的公平參數外 - 您可以決定何時釋放鎖,並且可以在多個點上執行此操作,因此最適合您。它的其他變體像ReentrantReadWriteLock允許你有許多非同步讀取,除非有寫入。不足之處在於,這是通過Java代碼解決的,這使得它比「本地」同步塊慢得多。這就是說:你應該只用它,如果你知道知道使用這個鎖的優化增益大於損失。

在正常情況下,你只能告訴在速度上的差異,如果你確實監視它,通過運行一個分析器之前,之後檢查速度在一個複雜的方式。

0

​​由於它允許JVM執行某些優化,例如biased locking,lock elision等,因此對於低爭用或最小爭用幾乎總是更快。這裏有一些更多的細節它是如何工作的:

假設某些監視器由線程A持有,而線程B請求此顯示器。在這種情況下,顯示器會將其狀態更改爲inflated。簡而言之,這意味着所有嘗試獲取此監視器的線程都將被置於操作系統級別,這非常昂貴。

現在,如果線程A在線程B請求它之前釋放監視器,所謂的rebias操作將以廉價(在現代CPU上)compare-and-swap操作執行。

讓我們來看看現在ReentrantLock。每個線程調用lock()lockInterruptibly()方法導致通過CAS操作完成鎖定嘗試。

結論:在低競爭的情況下,寧可​​。在較高的爭用情況下,更喜歡ReentrantLock。對於所有情況,很難肯定地說,考慮執行基準測試以找出哪種解決方案更快。