2013-04-22 71 views
2

在Java的實現鎖定中,沒有辦法自動將鎖從讀鎖升級到寫鎖。例如,下面的代碼片段失敗爲什麼一個鎖迫使你等到你真的有鎖?

ReentrantReadWriteLock lock = new ... 

lock.readLock().lock(); 

boolean mustWrite = false; 
// do somestuff and determine you must instead write! :-O 
if(mustWrite) { 
    lock.writeLock().lock(); 
    writeSomeStuff(); 
    lock.writeLock().unlock(); 
} 
lock.readLock.unlock(); 

寫入鎖定收購必須等待所有的讀鎖完成,所以它知道它不是覆蓋數據,讀者可能會潛在地閱讀。那很糟。所以,解決辦法是做這樣的事情:

if(mustWrite) { 
    lock.readLock().unlock(); // let go of read before writing 
    lock.writeLock().lock(); 
    writeSomeStuff(); 
    lock.writeLock().unlock(); 
    lock.readLock().lock(); // get back to reading 
} 

但這並不理想 - 說不定有人會去得到,當你解開讀,拿起寫之間做一些事情。無論如何,仔細檢查這些條件可能是一個好主意,但仍然 - 這很醜陋。

現在通常情況下,當你獲得一個鎖時,你希望強制你的代碼等待它實際獲得,然後再去做你正在做的事情。你不會只想相信你的鎖定機制,它會給你你的鎖,然後開始搞亂數據。

但是,爲什麼它會強制你停止執行?當你發出信號表示你想要鎖定時,當你真正閱讀等待?例如,爲什麼不能允許它是這樣的:

lock.writeLock().notifyIntentToLock(); // puts you in line to get the write lock 
             // everyone else will block until you both 
             // acquire and release the lock 
lock.readLock().unlock(); // proceed with the unlock so you don't deadlock 
lock.writeLock().makeGoodOnIntentToLock(); // actually acquire that lock 

因此從某種意義上說,當前鎖定功能可以作爲推論他們兩人被在同一時間完成的,像

​​

什麼設計決定會使他們不允許某種延遲的意圖鎖定?有沒有像我只是沒有看到的鎖設計的嚴重問題?

+0

鎖可以讓你保留它而不用等它,並允許你稍後再檢查一下,在這個時候你有希望已經獲得它,你不必再等待了。我其實覺得這是個不錯的主意。它可能比其他種類的鎖具有更復雜的實現 - 我不確定。人們可能能夠在較低級別的基元之上有效地實現它,就像讀寫器鎖在較簡單的基元之上實現一樣,例如互斥鎖和/或硬件比較和交換指令。 – Celada 2013-04-22 22:28:06

+0

Noob在這裏,但不會這樣的功能鼓勵應用程序非常貪婪?例如,如果我知道在程序中稍後需要一個文件,我可能會在開始的時候「notifyIntentToLock」,拒絕任何其他應用程序訪問它[可能]超過實際需要的時間。 – Supericy 2013-04-22 22:36:07

+0

@Supericy好吧,他們當然可以。但他們已經可以這麼做了 - 他們可以在開始時直接調用'lock'。所以它不像它引入任何新的誘惑來濫用那些已經不存在的API。 – corsiKa 2013-04-23 14:07:42

回答

0

所有你必須決定採取排它鎖後做的是:

  • 離開讀鎖,
  • 採取寫鎖和
  • 檢查病情再次
  • 根據結果​​,繼續或紓困。

至於意圖採取寫鎖,當多個併發意圖存在時會發生什麼?可能他們都必須檢查最初的條件,因爲沒有辦法確保誰會成爲受害者(在獲勝者後獲得鎖定)。

還有更多 - impl。的RW鎖吸收引導作爲讀取修改引起一致性流量的元數據 - 因此RW鎖不能很好地擴展。

相關問題