JDK1.8 StampedLock: 解決ReentrantReadWriteLock在讀多寫少狀況下,寫線程飢餓問題


ReentrantReadWriteLock 在沒有任何讀寫鎖時,才能夠取得寫入鎖,這可用於實現了悲觀讀取(Pessimistic Reading),工具

即若是執行中進行讀取時,常常可能有另外一執行要寫入的需求,爲了保持同步,ReentrantReadWriteLock 的讀取鎖定就可派上用場。線程

 

然而,若是讀取執行狀況不少,寫入不多的狀況下,使用 ReentrantReadWriteLock 可能會使寫入線程遭遇飢餓(Starvation)問題,對象

也就是寫入線程吃吃沒法競爭到鎖定而一直處於等待狀態。同步

StampedLock控制鎖有三種模式(寫,讀,樂觀讀),一個StampedLock狀態是由版本和模式兩個部分組成,鎖獲取方法返回一個數字做爲票據stamp,it

它用相應的鎖狀態表示並控制訪問,數字0表示沒有寫鎖被受權訪問。在讀鎖上分爲悲觀鎖和樂觀鎖。io

所謂的樂觀讀模式,也就是若讀的操做不少,寫的操做不多的狀況下,你能夠樂觀地認爲,寫入與讀取同時發生概率不多,所以不悲觀地使用徹底的讀取鎖定,監控

程序能夠查看讀取資料以後,是否遭到寫入執行的變動,再採起後續的措施(從新讀取變動信息,或者拋出異常) ,這一個小小改進,可大幅度提升程序的吞吐量!!程序


synchronized是在JVM層面上實現的,不但能夠經過一些監控工具監控synchronized的鎖定,並且在代碼執行時出現異常,JVM會自動釋放鎖定;
ReentrantLock、ReentrantReadWriteLock,、StampedLock都是對象層面的鎖定,要保證鎖定必定會被釋放,就必須將unLock()放到finally{}中;
StampedLock 對吞吐量有巨大的改進,特別是在讀線程愈來愈多的場景下;
當只有少許競爭者的時候,synchronized是一個很好的通用的鎖實現;
當線程增加可以預估,ReentrantLock是一個很好的通用的鎖實現;方法

相關文章
相關標籤/搜索