Java多線程 - 內置鎖與高級鎖機制

當多線程共享一個資源變量的時候,需要對線程加以控制,以保證線程是安全的,共享的資源被有效的使用。

內置鎖(監視鎖)

synchronized作用域代碼塊上,是一種內存可見的內置鎖。

synchronized是一種可重入鎖:同一個線程可以獲得它自己持有的鎖。

synchronized(x1) {
	code1;
	synchronized(x2) {
		code2;
	}
}

顯示鎖

Lock

ReentrantLock的作用相當於一種內置鎖,但不是一種替換內置加鎖的方法,而是當內置加鎖機制不適用時,作爲一種可選擇的高級功能。ReentrantLock也提供了可重入的加鎖語義,與synchronized相比,它還爲處理鎖的不可用性問題提供了更高級的靈活性。

Lock lock = new ReentrantLock ();
...
lock.lock()
try {
    // 更新對象狀態
    // 捕獲異常,並在必要時恢復不變性條件
}finally {
    lock.unlock();
}

鎖輪詢與定時鎖

可定時的與可輪詢的鎖獲取模式是由tryLock方法實現的,與無條件的鎖獲取模式相比,它具有更完善的錯誤恢復機制。

public boolean tryLock() {
	return sync.nonfairTryAcquire(1);
}

public boolean tryLock(long timeout, TimeUnit unit)
		throws InterruptedException {
	return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}

可中斷的鎖獲取操作

非塊結構的加鎖

公平性

在公平的鎖上,線程將按照它們發出請求的順序來獲取鎖,但在非公平的鎖上,則允許“插隊”。

/**
* 默認獲取的是非公平鎖
*/
public ReentrantLock() {
        sync = new NonfairSync();
}

public ReentrantLock(boolean fair) {
	sync = fair ? new FairSync() : new NonfairSync();
}


讀寫鎖

讀寫鎖實現類ReentrantReadWriteLock繼承於ReadWriteLock接口

在讀 - 寫鎖實現的加鎖策略中,允許多個讀操作同時進行,但每次只允許一個寫操作。

synchronized與lock鎖的選擇

在一些內置鎖無法滿足需要的情況下,ReentrantLock可以作爲一種高級工具。當需要一些高級功能時才應該使用ReentrantLock,這些功能包括:可定時的、可輪詢的與可中斷的鎖獲取操作,公平隊列,以及非塊結構的鎖。否則,還是應該優先使用synchronized。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章