2017-03-29 34 views
2

ReentrantReadWriteLock文檔中,說:ReentrantReadWriteLock - 爲什麼讀者不能獲取作家的鎖?

writer can acquire the read lock, but not vice-versa 

如果我理解正確的話就意味着,從相同線程可以執行:

//thread1 
lock.writeLock().lock() 
lock.readLock().lock() 
print("this line executes") 

這是有道理的:如果你已經鎖定write沒有其他線程可以輸入鎖定的代碼。但是如果你鎖定了read,如果沒有其他線程鎖定read,爲什麼不能在同一線程中輸入write塊?所以這不起作用:

//thread1 
lock.readLock().lock() 
lock.writeLock().lock() 
print("this line doesn't execute") 

你爲什麼在同一個線程鎖定write之前解鎖read

+0

如果您打算讀取和寫入,則不需要獲取*讀寫鎖。簡單地獲取寫入將使您能夠執行此操作。同樣,一旦讀取鎖定被執行,在讀取鎖定被釋放之前不能進行寫入鎖定。 – Michael

回答

2

ReentrantReadWriteLock並不意味着沒有遵循正常的規則鎖定。

如果一個線程爲了讀取目的而獲得一個鎖,它希望目標數據的值在鎖的持續時間內不會改變。否則會阻止可重複讀取。從概念上講,如果讓一個線程(相同或另一個線程)在讀鎖定結束時獲取寫鎖定,則違反了該規則。

如果一個線程獲得寫入鎖定,它隱含地具有讀取權限,因此獲得讀取鎖定可以被授予,因爲它並不真正違反鎖定的約定(如果我可以寫,我可以閱讀)也沒有鎖持有人的期望(我鎖定寫作,所以我是唯一一個現在可以閱讀或寫作的人)。

+0

當您已經擁有讀取鎖定時獲取寫入鎖定不必違反任何規則。它被稱爲_upgrading_,一些讀寫器庫允許它。當線程A和B都具有讀取權限並且線程A嘗試升級時,庫應該阻止其他線程獲取讀取,並且它必須阻塞線程A直到線程B放棄讀取。缺點是,如果線程B嘗試升級,那麼你會遇到死鎖。 ReadWriteLock的Javadoc顯式允許實現以任何方式工作,但是'ReentrantReadWriteLock'的作者選擇不允許升級。 –

-1

我其實不知道知道的答案,但它可能會幫你避免編寫死鎖的代碼。

假設您有兩個執行相同代碼的線程。兩個線程都獲得了讀鎖。然後,兩個線程都試圖獲取寫入鎖定。這兩個線程都不能繼續,直到另一個線程釋放其讀取鎖定,但兩個線程都不會在等待升級時釋放它的讀鎖。 (A)對不需要死鎖檢測的應用程序的性能產生負面影響,或者(B)對於不需要死鎖檢測的應用程序的性能有不利影響, API太複雜了。

通過禁止您將讀取鎖升級爲寫入鎖,它們使您無法編寫一個以特定方式死鎖的程序。

+0

_「我其實不知道答案......「_ - 如果你不知道答案,那麼請不要發佈答案。StackOverflow不是一個討論網站,答案應該是真實答案,不只是猜測(順便說一句,錯誤)。對於SO來說,它可以作爲未來讀者的好問題和答案***解決OP的問題是次要的,並且猜測只會污染網站。 –

相關問題