1. 程式人生 > >深入分析ReentrantLock公平鎖和非公平鎖的區別

深入分析ReentrantLock公平鎖和非公平鎖的區別

在ReentrantLock中包含了公平鎖和非公平鎖兩種鎖,通過檢視原始碼可以看到這兩種鎖都是繼承自Sync,而Sync又繼承自AbstractQueuedSynchronizer,而AbstractQueuedSynchronizer又繼承自AbstractOwnableSynchronizer,下面是類的繼承關係圖:


其中AbstractOwnableSynchronizer是提供了設定佔用當前鎖的執行緒資訊的方法,主要的鎖的實現還是在AbstractQueuedSynchronizer中實現的,在AbstractQueuedSynchronizer中通過CLH佇列實現了多執行緒鎖的排隊使用,但是該佇列的實現並不能保證鎖的公平競爭,但是在某些業務場景中會需要保證先到的執行緒先得到鎖,所以就有了公平鎖和非公平鎖的誕生。

通過分析ReentrantLock中的公平鎖和非公平鎖的實現,其中tryAcquire是公平鎖和非公平鎖實現的區別,下面的兩種型別的鎖的tryAcquire的實現,從中我們可以看出在公平鎖中,每一次的tryAcquire都會檢查CLH佇列中是否仍有前驅的元素,如果仍然有那麼繼續等待,通過這種方式來保證先來先服務的原則;而非公平鎖,首先是檢查並設定鎖的狀態,這種方式會出現即使佇列中有等待的執行緒,但是新的執行緒仍然會與排隊執行緒中的對頭執行緒競爭(但是排隊的執行緒是先來先服務的),所以新的執行緒可能會搶佔已經在排隊的執行緒的鎖,這樣就無法保證先來先服務,但是已經等待的執行緒們是仍然保證先來先服務的,所以總結一下公平鎖和非公平鎖的區別:

1、公平鎖能保證:老的執行緒排隊使用鎖,新執行緒仍然排隊使用鎖。
2、非公平鎖保證:老的執行緒排隊使用鎖;但是無法保證新執行緒搶佔已經在排隊的執行緒的鎖。

公平鎖的tryAcquire

/**
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
// !hasQueuedPredecessors()保證了不論是新的執行緒還是已經排隊的執行緒都順序使用鎖
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
非公平鎖的

/**
* Performs non-fair tryLock. tryAcquire is implemented in
* subclasses, but both need nonfair try for trylock method.
*/
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
// 新的執行緒可能搶佔已經排隊的執行緒的鎖的使用權
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ReentrantLock和LockSupport

http://blog.47777205.com/
http://blog.47777205.com/view/4
---------------------
作者:m47838704
來源:CSDN
原文:https://blog.csdn.net/m47838704/article/details/80013056
版權宣告:本文為博主原創文章,轉載請附上博文連結!