可重入鎖


  在看LinkedBlockingQueue的時候,有這么一句話:LinkedBlockingQueue采用可重入鎖(ReentrantLock)來保證在並發情況下的線程安全。

  因此,在這進行學習一下什么叫可重入鎖。

一:概述

1.什么是可重入

  什么是 “可重入”,可重入就是說某個線程已經獲得某個鎖,可以再次獲取鎖而不會出現死鎖。

 

2.可重入鎖有

  • synchronized
  • ReentrantLock

一:java可重入鎖-ReentrantLock實現細節

  ReentrantLock支持兩種獲取鎖的方式,一種是公平模型,一種是非公平模型。在繼續之前,咱們先把故事元素轉換為程序元素。

   

 

 

1.咱們先來說說公平鎖模型

  初始化時, state=0,表示無人搶占了打水權。這時候,村民A來打水(A線程請求鎖),占了打水權,把state+1,如下所示:

   

 

 

  線程A取得了鎖,把 state原子性+1,這時候state被改為1,A線程繼續執行其他任務,然后來了村民B也想打水(線程B請求鎖),線程B無法獲取鎖,生成節點進行排隊,如下圖所示:

   

 

 

  初始化的時候,會生成一個空的頭節點,然后才是B線程節點,這時候,如果線程A又請求鎖,是否需要排隊?答案當然是否定的,否則就直接死鎖了。當A再次請求鎖,就相當於是打水期間,同一家人也來打水了,是有特權的,這時候的狀態如下圖所示:

   

 

 

 

  到了這里,相信大家應該明白了什么是可重入鎖了吧。就是一個線程在獲取了鎖之后,再次去獲取了同一個鎖,這時候僅僅是把狀態值進行累加。如果線程A釋放了一次鎖,就成這樣了:

   

 

 

  僅僅是把狀態值減了,只有線程A把此鎖全部釋放了,狀態值減到0了,其他線程才有機會獲取鎖。當A把鎖完全釋放后,state恢復為0,然后會通知隊列喚醒B線程節點,使B可以再次競爭鎖。當然,如果B線程后面還有C線程,C線程繼續休眠,除非B執行完了,通知了C線程。注意,當一個線程節點被喚醒然后取得了鎖,對應節點會從隊列中刪除。


2.非公平鎖模型

  如果你已經明白了前面講的公平鎖模型,那么非公平鎖模型也就非常容易理解了。當線程A執行完之后,要喚醒線程B是需要時間的,而且線程B醒來后還要再次競爭鎖,所以如果在切換過程當中,來了一個線程C,那么線程C是有可能獲取到鎖的,如果C獲取到了鎖,B就只能繼續乖乖休眠了。這里就不再畫圖說明了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM