JAVA 8 併發增強 (2)樂觀讀
阿新 • • 發佈:2018-12-12
它是java8在java.util.concurrent.locks新增的一個類。/* * J8添加了StampedLock類,它用來實現樂觀讀。 首先呼叫tryOptimisticRead方法,此時會獲得一個“印戳”。然後讀取值並檢查“印戳” * 是否仍然有效(例如其他執行緒已經獲得了一個讀鎖)。如果有效,就可以使用這個值。如果無效,就會獲得一個讀鎖(它會阻塞所有的寫鎖) */ public class Vector { private int size; private Object[] elements; private StampedLock lock = new StampedLock(); public Object get(int n) { long stamp = lock.tryOptimisticRead(); Object[] currentElements = elements; int currentSize = size; if (!lock.validate(stamp)) {// 某個執行緒有了一個寫鎖 stamp = lock.readLock();// 獲得一個悲觀鎖? currentElements = elements; currentSize = size; lock.unlock(stamp); } return n < currentSize ? currentElements[n] : null; } }
ReentrantReadWriteLock 在沒有任何讀寫鎖時,才可以取得寫入鎖,實現了悲觀讀取(Pessimistic Reading),如果讀取執行情況很多,寫入很少的情況下,使用 ReentrantReadWriteLock 可能使寫入執行緒吃吃無法競爭到鎖定而一直處於等待狀態。
StampedLock控制鎖有三種模式(寫,讀,樂觀讀),一個StampedLock狀態是由版本和模式兩個部分組成,鎖獲取方法返回一個數字作為票據stamp,它用相應的鎖狀態表示並控制訪問,數字0表示沒有寫鎖被授權訪問。在讀鎖上分為悲觀鎖和樂觀鎖。
所謂的樂觀讀模式,也就是若讀的操作很多,寫的操作很少的情況下,你可以樂觀地認為,寫入與讀取同時發生機率很少,因此不悲觀地使用完全的讀取鎖定,程式可以檢視讀取資料之後,是否遭到寫入執行的變更,再採取後續的措施(重新讀取變更資訊,或者丟擲異常),從而大幅度提高程式的吞吐量。