ReentrantLock中的公平鎖與非公平鎖

2022-08-31 18:30:13 字數 1487 閱讀 6645

reentrantlock是一種可重入鎖,可以等同於synchronized的使用,但是比synchronized更加的強大、靈活。

乙個可重入的排他鎖,它具有與使用 synchronized 方法和語句所訪問的隱式監視器鎖定相同的一些基本行為和語義,但功能更強大。reentrantlock 將由最近成功獲得鎖定,並且還沒有釋放該鎖定的執行緒所擁有。當鎖定沒有被另乙個執行緒所擁有時,呼叫 lock 的執行緒將成功獲取該鎖定並返回。如果當前執行緒已經擁有該鎖定,此方法將立即返回。可以使用 isheldbycurrentthread() 和 getholdcount() 方法來檢查此情況是否發生。

reentrantlock內部擁有乙個sync內部類,該內部類繼承自aqs,該內部類有兩個子類fairsync和nonfairsync,分別代表了公平鎖和非公平鎖,reentrantlock預設使用非公平鎖
那麼reentrantlock內部的公平鎖和非公平鎖有什麼區別呢?
區別主要在於兩種鎖實現的獲取鎖的方式,tryacquire方法實現的不同:

首先來看看非公平鎖:

protected final boolean tryacquire(int acquires)

final boolean nonfairtryacquire(int acquires)

} else if (current == getexclusiveownerthread())

return false;//否則,獲取鎖失敗

}可以看到,非公平鎖獲取鎖的過程是:首先判斷當前鎖是否被其他執行緒持有,如果是,直接返回失敗,否則嘗試獲取鎖

再來看看公平鎖的加鎖過程:

protected final boolean tryacquire(int acquires)

}else if (current == getexclusiveownerthread())

return false;

}對比上面的非公平鎖的加鎖過程,可以看到公平鎖多了乙個hasqueuedpredecessors方法的判斷,來看看該方法的實現:

public final boolean hasqueuedpredecessors()

其實就是判斷當前執行緒是否為clh佇列的頭節點

我們知道,嘗試獲取鎖失敗的執行緒都會被放入到clh佇列中,然後自旋嘗試獲取鎖。對比公平鎖和非公平鎖的獲取方式可以看到,公平鎖之所以公平,是因為後續的執行緒必須進入到clh同步佇列中排隊等候獲取鎖,但是分公平鎖不需要,如果某個執行緒嘗試獲取鎖的時候當前鎖剛好被釋放掉,那麼它可以直接嘗試獲取鎖,如果獲取鎖成功,直接執行,獲取失敗時,才進入到clh同步佇列

通過上面的分析可以看到,公平鎖是將所有執行緒依次放入clh同步佇列,然後再從佇列中依次取出來執行;而非公平鎖是部分已經進入同步佇列的執行緒會像公平鎖一樣獲取鎖,但是其他尚且沒有進入同步佇列的執行緒可以與clh同步佇列中的首節點執行緒競爭鎖;這也是為什麼非公平鎖效能比公平鎖效能更佳的原因

ReentrantLock中公平鎖與非公平鎖的區別

reentrantlock 通過模板模式使用sync繼承了abstractqueuedsynchronizer 同步器 繼而又使用了fairsync,nonfairsync類來覆寫了sync的方法,在使用reentrantlock時,通過構造方法確定使用公平鎖還是非公平鎖。公平鎖與非公平鎖的差別主要...

ReentrantLock 的簡單分析

reentantlock繼承介面lock並實現了介面中定義的方法,他是一種可重入鎖,除了能完 成synchronized所能完成的所有工作外,還提供了諸如可響應中斷鎖 可輪詢鎖請求 定時鎖等 避免多執行緒死鎖的方法。void lock 執行此方法時,如果鎖處於空閒狀態,當前執行緒將獲取到鎖.相反,如...

對ReentrantLock的認識?

顧名思義,reentrantlock是重入鎖。它實現了lock介面,是基於aqs 一種用於構建同步器的框架 構造出來的一種同步器。同synchronized一樣,reentrantlock也是可重入的,與synchronized相比增加了一些高階功能,主要有以下三項 等待可中斷 可實現公平鎖 鎖可以...