reentrantlock
是可重入的獨佔鎖,同時只能有乙個執行緒可以獲取該鎖,其他獲取該鎖的執行緒會被阻塞而被放入該鎖的aqs阻塞佇列裡面。
根據引數來決定其內部是乙個公平鎖還是非公平鎖。
預設非公平鎖。
public
reentrantlock()
public
reentrantlock
(boolean fair)
sync
類直接繼承自aqs,它的子類nonfairsync
、fairsync
分別實現了獲取鎖的非公平與公平策略。
非公平:先嘗試獲取鎖的執行緒並不一定比後嘗試獲取鎖的執行緒優先獲取鎖。
獲取鎖:void lock()
final
void
lock()
1、設定state的狀態值為1compareandsetstate(0, 1)
aqs的state狀態值表示執行緒獲取鎖的可重入次數,預設為0表示當前鎖沒有被任何執行緒持有,當乙個執行緒第一次獲取該鎖時會嘗試使用cas設定state的值為1,在該執行緒沒有釋放鎖的情況下第二次獲取該鎖後,狀態值被設定為2,這就是可重入次數。
2、如果cas成功則當前執行緒獲取了該鎖,然後記錄該鎖的持有者為當前執行緒setexclusiveownerthread(thread.currentthread())
。
3、如果cas失敗,會呼叫acquire(1);
public
final
void
acquire
(int arg)
final
boolean
nonfairtryacquire
(int acquires)
}else
if(current ==
getexclusiveownerthread()
)return
false
;}
執行nonfairtryacquire
如果返回true,當前執行緒獲取了該鎖;
如果返回false,則其會被放入aqs阻塞佇列acquirequeued(addwaiter(node.exclusive), arg)
非公平鎖的體現
明明是執行緒a先請求獲取該鎖,但執行緒b在獲取鎖前並沒有檢視aqs佇列裡面是否有比自己更早請求該鎖的執行緒,而是使用了搶奪策略。
公平鎖的tryacquire
與非公平的類似:
protected
final
boolean
tryacquire
(int acquires)
}else
if(current ==
getexclusiveownerthread()
)return
false
;}
不同之處在於在設定cas前新增了hasqueuedpredecessors()
,該方法是實現公平性的核心**:
public
final
boolean
hasqueuedpredecessors()
h == t
:隊列為空
s = h.next
:s為佇列的第乙個元素
h != t && s == null
:有乙個元素將要作為aqs的第乙個節點入佇列
h != t && s != null && s.thread != thread.currentthread()
:佇列裡面的第乙個元素不是當前執行緒
ReentrantLock中公平鎖與非公平鎖的區別
reentrantlock 通過模板模式使用sync繼承了abstractqueuedsynchronizer 同步器 繼而又使用了fairsync,nonfairsync類來覆寫了sync的方法,在使用reentrantlock時,通過構造方法確定使用公平鎖還是非公平鎖。公平鎖與非公平鎖的差別主要...
ReentrantLock中的公平鎖與非公平鎖
reentrantlock是一種可重入鎖,可以等同於synchronized的使用,但是比synchronized更加的強大 靈活。乙個可重入的排他鎖,它具有與使用 synchronized 方法和語句所訪問的隱式監視器鎖定相同的一些基本行為和語義,但功能更強大。reentrantlock 將由最近...
公平鎖和非公平鎖
公平鎖和非公平鎖的不同是發生在乙個新的執行緒搶占乙個鎖的情況下。1.對於非公平鎖,當乙個新的執行緒想要得到乙個鎖,而這時鎖恰好沒有被別的執行緒占有,那麼這時候這個新的執行緒就可以無視其他執行緒在等待佇列中的排隊,而直接獲取這個鎖,而且不用先加入等待佇列。2,公平鎖,就是乙個新的執行緒想要得到乙個鎖,...