1、支持樂觀讀鎖、悲觀讀鎖、悲觀寫鎖三種鎖粒度。
1-1、樂觀讀鎖(tryOptimisticRead):多線程情況下,支持多線程去讀同時少量的去寫,弊端很明顯:當發生多線程去讀同時 又寫的情況下,數據無法保證一致性。
1-2、悲觀讀鎖(readLock):即是共享讀,支持多線程同時去讀。當發生其中一個線程被寫鎖獨佔的時候,其他線程全部等待。
1-3、悲觀寫鎖(writeLock):多線程情況下,當發生只有一個線程被寫鎖獨佔的情況,其餘線程全部等待。
2、源碼:https://segmentfault.com/a/1190000015808032?utm_source=tag-newest
3、樂觀讀的情況下,如何保證數據的一致性呢?(通過校驗stamp來將鎖的粒度升級爲悲觀讀鎖)
long stamp = lock.tryOptimisticRead(); // 非阻塞獲取版本信息
copyVaraibale2ThreadMemory(); // 拷貝變量到線程本地堆棧
if(!lock.validate(stamp)){ // 校驗
long stamp = lock.readLock(); // 獲取讀鎖
try {
copyVaraibale2ThreadMemory(); // 拷貝變量到線程本地堆棧
} finally {
lock.unlock(stamp); // 釋放悲觀鎖
}
}
useThreadMemoryVarables(); // 使用線程本地堆棧裏面的數據進行操作
//例如
double distanceFromOrigin() {
// 嘗試獲取樂觀讀鎖
long stamp = sl.tryOptimisticRead();
// 將全部變量拷貝到方法體棧內
double currentX = x, currentY = y;
// 檢查在(1)獲取到讀鎖票據後,鎖有沒被其他寫線程排它性搶佔
if (!sl.validate(stamp)) {
// 如果被搶佔則獲取一個共享讀鎖(悲觀獲取)
stamp = sl.readLock();
try {
// 將全部變量拷貝到方法體棧內
currentX = x;
currentY = y;
} finally {
// 釋放共享讀鎖
sl.unlockRead(stamp);
}
}
// 返回計算結果(7)
return Math.sqrt(currentX * currentX + currentY * currentY);
}
4、StampedLock的中斷問題導致CPU爆滿 :http://ifeve.com/stampedlock-bug-cpu/