Java併發編程原理與實戰三十九:JDK8新增鎖StampedLock詳解

一、StampedLock是作什麼的?多線程

-----》它是ReentrantReadWriteLock 的加強版,是爲了解決ReentrantReadWriteLock的一些不足。
 
二、ReentrantReadWriteLock有什麼不足之處呢?
------》咱們都知道,ReentrantReadWriteLock是讀寫鎖,在多線程環境下,大多數狀況是讀的狀況遠遠大於寫的操做,所以可能致使寫的飢餓問題。(換人話來講的話,讀操做一直都能搶佔到CPU時間片,而寫操做一直搶不了)
 
三、爲何會致使寫操做會出血飢餓問題呢?
-----》ReentrantReadWriteLock 寫鎖的互斥的
(讀和讀---不互斥, 讀和寫---互斥,寫和寫----互斥),懂了嗎?
 
四、正由於ReentrantReadWriteLock出現了 讀和寫是互斥的狀況,這個地方須要優化,所以就出現了StampedLock!
 
五、StampedLock是讀鎖並不會阻塞寫鎖。這裏就有朋友會問,若是這樣設計的話,那麼怎樣保證讀和寫的一致性呢?
-----》StampedLock的設計思路也比較簡單,就是在讀的時候發現有寫操做,再去讀多一次。(思想上來講)
 
六、那下一個問題就是StampedLock是怎樣知道讀的時候發生了寫操做呢?
-----》咱們的StampedLock有兩種鎖,一種是悲觀鎖,另一種是樂觀鎖。若是線程拿到樂觀鎖就讀和寫不互斥,若是拿到悲觀鎖就讀和寫互斥。
 
七、看StampedLock源碼的時候,能夠看writeLock()和trywriteLock(), tryOptimisticRead()這是本API中最有亮點的方法(樂觀鎖)。
 
 
==============================================================
 
 
public class Demo {
private int balance;
private StampedLock lock = new StampedLock();
public void conditionReadWrite (int value) {
// 首先判斷balance的值是否符合更新的條件
long stamp = lock.readLock();
while (balance > 0) {
long writeStamp = lock.tryConvertToWriteLock(stamp);
if(writeStamp != 0) { // 成功轉換成爲寫鎖
stamp = writeStamp;
balance += value;
break;
} else {
// 沒有轉換成寫鎖,這裏須要首先釋放讀鎖,而後再拿到寫鎖
lock.unlockRead(stamp);
// 獲取寫鎖
stamp = lock.writeLock();
}
  }
lock.unlock(stamp);
}
public void optimisticRead() {
long stamp = lock.tryOptimisticRead();
int c = balance;
// 這裏可能會出現了寫操做,所以要進行判斷
if(!lock.validate(stamp)) {
// 要重新讀取
long readStamp = lock.readLock();
c = balance;
stamp = readStamp;
}
/// 
lock.unlockRead(stamp);
}
public void read () {
long stamp = lock.readLock();
lock.tryOptimisticRead();
int c = balance;
// ...
lock.unlockRead(stamp);
}
public void write(int value) {
long stamp = lock.writeLock();
balance += value;
lock.unlockWrite(stamp);
}
 
}
 
====================================================
 
StampedLock的性能是遠遠好過ReentrantReadWriteLock的。那爲何還存在ReentrantReadWriteLock呢?
------》根據咱們上述的代碼,咱們知道使用StampedLock,編寫代碼上相對繁瑣些。ReentranReadWriteLock比較簡單些。
 
 
悲觀鎖:每次拿數據的時候就去鎖上。
樂觀鎖:每次去拿數據的時候,都沒鎖上,而是判斷標記位是否有被修改,若是有修改就再去讀一次。
(就像不少我的去桌子上看今天老師佈置的做業題,另外桌子旁邊有一個牌子,紅色面表明「做業題已經被修改過了」,白色面表明「題目是最新的」。第一我的去看做業題,再看了下牌子,牌子是白色的,做業題是最新的。可是有一我的去看做業題,看完以後,再看隔壁的牌子,牌子變成紅色了,因而他趕忙回去看了一下題目,果真題目已經被改過了,因而他再看了一次,再確認一次牌子顏色,都沒問題以後,就放心走了。)
相關文章
相關標籤/搜索