《Java併發編程藝術---顯示鎖,可重入鎖,讀寫鎖---02

1. Lock

互斥的,在請求鎖時如果該鎖別其它線程獲取的時候,該線程將會被阻塞,放在該鎖的阻塞隊列中,當線程釋放鎖時,被阻塞的線程會被激活來判斷是否是阻塞隊列的頭結點將會獲得鎖,依次下去。

其中的阻塞隊列是FIFO隊列,這也是最簡單的線程調用策略了。

2. 可重入鎖(ReentrantLock)

相對於Lock,可重入鎖式支持同一個線程獲取鎖的。列入遞歸方法,在方法中還可以調用該方法的。
但是Lock不支持重入,會出現線程被自己阻塞的情況。(當前線程正在運行,當該線程請求鎖時,返回的false,這樣改線程會被阻塞,這樣正在運行的該線程也會被阻塞)

重點知識

  • 如何實現可重入
  • 如何實現公平性(原則是:現請求鎖的線程,先獲得鎖)

公平性

公平

其實就是按照FIFO的原則,每次在等待隊列的頭部獲取線程來得到鎖

  • 性能比較低,因爲每次都要切換

非公平

  • 默認是非公平的

  • 相比於公平,非公平性能更高,但是可能會產生死鎖。

3. 讀寫鎖

將排他鎖分成讀寫鎖,也就是將讀操做和寫操作分開控制。
同一時刻可以允許多個讀鎖,但是當又寫鎖時,其它所有的讀寫操做都要被阻塞,當該讀鎖釋放時,被阻塞的讀寫操做才恢復。這樣保證數據的一直性,保證不會出現髒讀的情況。

特點

  • 公平性

  • 可重入性

  • 鎖降級(寫鎖可以降級爲讀鎖)

4. ReentrantReadWriteLock

讀寫狀態的設計

通過將32位整形變量分成高16位和低16位,高16位爲寫狀態,低16位爲讀狀態。
通過位操作來實現對讀寫狀態的維護

寫鎖的獲取與釋放

寫鎖的獲取與釋放和Lock很類似,因爲寫鎖其實也會是排他鎖。同一時刻只有唯一的一個寫操作獲取寫鎖。

讀鎖的獲取與釋放

鎖降級

先獲取讀鎖,準備好寫入的數據,在獲取讀鎖,這樣就實現了從寫鎖到讀鎖的降級。

  • 爲什麼不直接釋放寫鎖呢?還要獲取讀鎖,這樣講避免,釋放寫鎖之後,其他線程獲取寫鎖將數據更改,但是當前線程是感知不到這種變化的。如果獲取讀鎖,要獲取讀鎖的線程將會被阻塞,這樣就避免了這種情況。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章