1. 程式人生 > >JAVA 8 併發增強 (2)樂觀讀

JAVA 8 併發增強 (2)樂觀讀

/*
 * 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;
	}
}
它是java8在java.util.concurrent.locks新增的一個類。
ReentrantReadWriteLock 在沒有任何讀寫鎖時,才可以取得寫入鎖,實現了悲觀讀取(Pessimistic Reading),如果讀取執行情況很多,寫入很少的情況下,使用 ReentrantReadWriteLock 可能使寫入執行緒吃吃無法競爭到鎖定而一直處於等待狀態。
StampedLock控制鎖有三種模式(寫,讀,樂觀讀),一個StampedLock狀態是由版本和模式兩個部分組成,鎖獲取方法返回一個數字作為票據stamp,它用相應的鎖狀態表示並控制訪問,數字0表示沒有寫鎖被授權訪問。在讀鎖上分為悲觀鎖和樂觀鎖。
所謂的樂觀讀模式,也就是若讀的操作很多,寫的操作很少的情況下,你可以樂觀地認為,寫入與讀取同時發生機率很少,因此不悲觀地使用完全的讀取鎖定,程式可以檢視讀取資料之後,是否遭到寫入執行的變更,再採取後續的措施(重新讀取變更資訊,或者丟擲異常),從而大幅度提高程式的吞吐量。