日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

ReentrantReadWriteLock源码解析

發(fā)布時(shí)間:2024/4/13 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ReentrantReadWriteLock源码解析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

概述

  ReentrantReadWriteLock是Lock的另一種實(shí)現(xiàn)方式,我們已經(jīng)知道了ReentrantLock是一個(gè)排他鎖,同一時(shí)間只允許一個(gè)線程訪問(wèn),而ReentrantReadWriteLock允許多個(gè)讀線程同時(shí)訪問(wèn),但不允許寫(xiě)線程和讀線程、寫(xiě)線程和寫(xiě)線程同時(shí)訪問(wèn)。相對(duì)于排他鎖,提高了并發(fā)性。在實(shí)際應(yīng)用中,大部分情況下對(duì)共享數(shù)據(jù)(如緩存)的訪問(wèn)都是讀操作遠(yuǎn)多于寫(xiě)操作,這時(shí)ReentrantReadWriteLock能夠提供比排他鎖更好的并發(fā)性和吞吐量。

  讀寫(xiě)鎖內(nèi)部維護(hù)了兩個(gè)鎖,一個(gè)用于讀操作,一個(gè)用于寫(xiě)操作。所有 ReadWriteLock實(shí)現(xiàn)都必須保證 writeLock操作的內(nèi)存同步效果也要保持與相關(guān) readLock的聯(lián)系。也就是說(shuō),成功獲取讀鎖的線程會(huì)看到寫(xiě)入鎖之前版本所做的所有更新

  ReentrantReadWriteLock支持以下功能:

    1)支持公平和非公平的獲取鎖的方式;

    2)支持可重入。讀線程在獲取了讀鎖后還可以獲取讀鎖;寫(xiě)線程在獲取了寫(xiě)鎖之后既可以再次獲取寫(xiě)鎖又可以獲取讀鎖

    3)還允許從寫(xiě)入鎖降級(jí)為讀取鎖,其實(shí)現(xiàn)方式是:先獲取寫(xiě)入鎖,然后獲取讀取鎖,最后釋放寫(xiě)入鎖。但是,從讀取鎖升級(jí)到寫(xiě)入鎖是不允許的;

    4)讀取鎖和寫(xiě)入鎖都支持鎖獲取期間的中斷;

    5)Condition支持。僅寫(xiě)入鎖提供了一個(gè) Conditon 實(shí)現(xiàn);讀取鎖不支持 Conditon?,readLock().newCondition() 會(huì)拋出 UnsupportedOperationException。?

示例(JDK自帶示例)

示例1:利用重入來(lái)執(zhí)行升級(jí)緩存后的鎖降級(jí)

class CachedData {
??? Object data;
??? volatile boolean cacheValid;??? //緩存是否有效
??? ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

??? void processCachedData() {
??????? rwl.readLock().lock();??? //獲取讀鎖
??????? //如果緩存無(wú)效,更新cache;否則直接使用data
??????? if (!cacheValid) {
??????????? // Must release read lock before acquiring write lock
??????????? //獲取寫(xiě)鎖前須釋放讀鎖
??????????? rwl.readLock().unlock();
??????????? rwl.writeLock().lock();?? ?
??????????? // Recheck state because another thread might have acquired
??????????? //?? write lock and changed state before we did.
??????????? if (!cacheValid) {
??????????????? data = ...
??????????????? cacheValid = true;
??????????? }
??????????? // Downgrade by acquiring read lock before releasing write lock
??????????? //鎖降級(jí),在釋放寫(xiě)鎖前獲取讀鎖
??????????? rwl.readLock().lock();
??????????? rwl.writeLock().unlock(); // Unlock write, still hold read
??????? }

??????? use(data);
??????? rwl.readLock().unlock();??? //釋放讀鎖
??? }
}

示例2:使用 ReentrantReadWriteLock 來(lái)提高 Collection 的并發(fā)性

class RWDictionary {
??? private final Map<String, Data> m = new TreeMap<String, Data>();
??? private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
??? private final Lock r = rwl.readLock();??? //讀鎖
??? private final Lock w = rwl.writeLock();??? //寫(xiě)鎖

??? public Data get(String key) {
??????? r.lock();
??????? try { return m.get(key); }
??????? finally { r.unlock(); }
??? }
??? public String[] allKeys() {
??????? r.lock();
??????? try { return m.keySet().toArray(); }
??????? finally { r.unlock(); }
??? }
??? public Data put(String key, Data value) {
??????? w.lock();
??????? try { return m.put(key, value); }
??????? finally { w.unlock(); }
??? }
??? public void clear() {
??????? w.lock();
??????? try { m.clear(); }
??????? finally { w.unlock(); }
??? }
}

?

源碼解析

ReentrantReadWriteLock 是基于AQS實(shí)現(xiàn)的(參考AbstractQueuedSynchronizer源碼解析),它的自定義同步器(繼承AQS)需要在同步狀態(tài)(一個(gè)整型變量state)上維護(hù)多個(gè)讀線程和一個(gè)寫(xiě)線程的狀態(tài),使得該狀態(tài)的設(shè)計(jì)成為讀寫(xiě)鎖實(shí)現(xiàn)的關(guān)鍵。如果在一個(gè)整型變量上維護(hù)多種狀態(tài),就一定需要“按位切割使用”這個(gè)變量,讀寫(xiě)鎖將變量切分成了兩個(gè)部分,高16位表示讀,低16位表示寫(xiě)。

public class ReentrantReadWriteLockimplements ReadWriteLock, java.io.Serializable {} { /** Inner class providing readlock */private final ReentrantReadWriteLock.ReadLock readerLock;/** Inner class providing writelock */private final ReentrantReadWriteLock.WriteLock writerLock;/** Performs all synchronization mechanics */final Sync sync; }

ReadLock與WriteLock

public static class ReadLock implements Lock, java.io.Serializable {private static final long serialVersionUID = -5992448646407690164L;private final Sync sync;protected ReadLock(ReentrantReadWriteLock lock) {sync = lock.sync;}public void lock() {sync.acquireShared(1);}public void lockInterruptibly() throws InterruptedException {sync.acquireSharedInterruptibly(1);}public boolean tryLock() {return sync.tryReadLock();}public boolean tryLock(long timeout, TimeUnit unit)throws InterruptedException {return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));}public void unlock() {sync.releaseShared(1);}public Condition newCondition() {throw new UnsupportedOperationException();}} public static class WriteLock implements Lock, java.io.Serializable {private static final long serialVersionUID = -4992448646407690164L;private final Sync sync;protected WriteLock(ReentrantReadWriteLock lock) {sync = lock.sync;}public void lock() {sync.acquire(1);}public void lockInterruptibly() throws InterruptedException {sync.acquireInterruptibly(1);}public boolean tryLock( ) {return sync.tryWriteLock();}public boolean tryLock(long timeout, TimeUnit unit)throws InterruptedException {return sync.tryAcquireNanos(1, unit.toNanos(timeout));}public void unlock() {sync.release(1);}public Condition newCondition() {return sync.newCondition();}public boolean isHeldByCurrentThread() {return sync.isHeldExclusively();}public int getHoldCount() {return sync.getWriteHoldCount();}}

?ReadLock與WriteLock比較:

  • ReadLock使用共享模式,WriteLock使用獨(dú)占模式
  • ReadLock與WriteLock使用同一個(gè)Sync

public ReentrantReadWriteLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();readerLock = new ReadLock(this);writerLock = new WriteLock(this);}

?

Sync

數(shù)據(jù)結(jié)構(gòu)

?? abstract static class Sync extends AbstractQueuedSynchronizer {
??????? private static final long serialVersionUID = 6317671515068378041L;

??????? /*
?? ??? ?SHARED_SHIFT相關(guān)變量與方法為鎖狀態(tài)訪問(wèn)邏輯。
???????? */
?? ??? ?//低16位為寫(xiě)鎖狀態(tài),高16位為讀鎖狀態(tài)。
??????? static final int SHARED_SHIFT?? = 16;
?? ??? ?//讀鎖每次增加的單位(因?yàn)樵诟?6位,所以加1,即相當(dāng)于整個(gè)int加 1個(gè)SHARED_UNIT??? )
??????? static final int SHARED_UNIT??? = (1 << SHARED_SHIFT);
?? ??? ?//讀鎖最大數(shù)(2^16 -1 )
??????? static final int MAX_COUNT????? = (1 << SHARED_SHIFT) - 1;
?? ??? ?//寫(xiě)鎖狀態(tài)掩碼(2^16-1)
??????? static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;

??????? /**返回讀鎖數(shù)量 ,高16位(無(wú)符號(hào)右移16位) */
??????? static int sharedCount(int c)??? { return c >>> SHARED_SHIFT; }
??????? /** 返回寫(xiě)鎖數(shù)量

? ? ? ? *EXCLUSIVE_MASK,高位全是0,與操作返回寫(xiě)狀態(tài)數(shù)量

??????? */
??????? static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }

??????? /**
???????? * A counter for per-thread read hold counts.
???????? * Maintained as a ThreadLocal; cached in cachedHoldCounter
???????? */

?????? //當(dāng)前讀線程的計(jì)數(shù)器
??????? static final class HoldCounter {
??????????? int count = 0;??? //當(dāng)前讀線程總的重入次數(shù)
??????????? //線程ID
??????????? final long tid = getThreadId(Thread.currentThread());
??????? }

??????? /**
???????? * ThreadLocal 子類(lèi)
???????? */
??????? static final class ThreadLocalHoldCounter
??????????? extends ThreadLocal<HoldCounter> {
??????????? public HoldCounter initialValue() {
??????????????? return new HoldCounter();
??????????? }
??????? }

??????? /**
???????? */
??????? private transient ThreadLocalHoldCounter readHolds;

?????? //當(dāng)前線程緩存的HoldCounter
??????? private transient HoldCounter cachedHoldCounter;

??????? /**
???????? */
??????? private transient Thread firstReader = null;
??????? private transient int firstReaderHoldCount;

??????? Sync() {
??????????? readHolds = new ThreadLocalHoldCounter();
??????????? setState(getState()); // ensures visibility of readHolds
??????? }
}

state結(jié)構(gòu)

讀鎖的獲取與釋放

讀鎖的lock和unlock的實(shí)際實(shí)現(xiàn)對(duì)應(yīng)Sync的 tryAcquireShared 和 tryReleaseShared方法。

protected final int tryAcquireShared(int unused) {Thread current = Thread.currentThread();int c = getState();如果寫(xiě)鎖線程數(shù) != 0 ,且獨(dú)占鎖不是當(dāng)前線程則返回失敗,因?yàn)榇嬖阪i降級(jí)(先write,后read),if (exclusiveCount(c) != 0 && //獲取寫(xiě)鎖數(shù)量getExclusiveOwnerThread() != current)return -1;int r = sharedCount(c); //獲取讀鎖數(shù)量。if (!readerShouldBlock() && //讀操作不被阻塞。r < MAX_COUNT && //讀鎖數(shù)量未到最大值compareAndSetState(c, c + SHARED_UNIT) //競(jìng)爭(zhēng)成功) {//r == 0,表示第一個(gè)讀鎖線程,第一個(gè)讀鎖firstRead是不會(huì)加入到readHolds中if (r == 0) {firstReader = current; // 設(shè)置第一個(gè)讀線程firstReaderHoldCount = 1; // 讀線程占用的資源數(shù)為1} else if (firstReader == current) {// 當(dāng)前線程為第一個(gè)讀線程,表示第一個(gè)讀鎖線程重入,則第一個(gè)線程占用資源+1firstReaderHoldCount++;} else {// 獲取計(jì)數(shù)器HoldCounter rh = cachedHoldCounter;if (rh == null || rh.tid != getThreadId(current))// 計(jì)數(shù)器為空或者計(jì)數(shù)器的tid不為當(dāng)前正在運(yùn)行的線程的tid,則獲取當(dāng)前 線程對(duì)應(yīng)的計(jì)數(shù)器cachedHoldCounter = rh = readHolds.get();else if (rh.count == 0)//計(jì)數(shù)為0,則表示未加入到緩存,加入到readHolds中readHolds.set(rh);//把當(dāng)前線程的計(jì)數(shù)加1rh.count++;}//返回1,則表示acquire成功,return 1;}return fullTryAcquireShared(current);}final int fullTryAcquireShared(Thread current) {/** This code is in part redundant with that in* tryAcquireShared but is simpler overall by not* complicating tryAcquireShared with interactions between* retries and lazily reading hold counts.*/HoldCounter rh = null;for (;;) {int c = getState();if (exclusiveCount(c) != 0) {//寫(xiě)線程不是本線程,則返回-1if (getExclusiveOwnerThread() != current)return -1;// else we hold the exclusive lock; blocking here// would cause deadlock.} else if (readerShouldBlock()) { // 寫(xiě)線程數(shù)量為0并且讀線程被阻塞// Make sure we're not acquiring read lock reentrantlyif (firstReader == current) { //第一個(gè)讀線程是本線程。// assert firstReaderHoldCount > 0;} else {//第一個(gè)讀線程不是本線程。if (rh == null) {//獲取緩存holdrh = cachedHoldCounter;if (rh == null || rh.tid != getThreadId(current)) {//獲取本線程的Holdrh = readHolds.get();if (rh.count == 0)readHolds.remove(); //如果為0,則需要移出。}}if (rh.count == 0)return -1;}}if (sharedCount(c) == MAX_COUNT) // 讀鎖數(shù)量為最大值,拋出異常throw new Error("Maximum lock count exceeded");if (compareAndSetState(c, c + SHARED_UNIT)) { // 比較并且設(shè)置成功if (sharedCount(c) == 0) { // 讀線程數(shù)量為0,設(shè)置第一個(gè)讀線程firstReader = current;firstReaderHoldCount = 1;} else if (firstReader == current) {//第一個(gè)讀線程計(jì)數(shù)加1.firstReaderHoldCount++;} else {//不是第一個(gè)線程,則獲取計(jì)數(shù)器。if (rh == null)rh = cachedHoldCounter;if (rh == null || rh.tid != getThreadId(current))rh = readHolds.get();else if (rh.count == 0)readHolds.set(rh);rh.count++;cachedHoldCounter = rh; // cache for release}return 1;}}}

?

讀鎖acquire流程圖

?

注意:

更新成功后會(huì)在firstReaderHoldCount中或readHolds(ThreadLocal類(lèi)型的)的本線程副本中記錄當(dāng)前線程重入數(shù)(23行至43行代碼),這是為了實(shí)現(xiàn)jdk1.6中加入的getReadHoldCount()方法的,這個(gè)方法能獲取當(dāng)前線程重入共享鎖的次數(shù)(state中記錄的是多個(gè)線程的總重入次數(shù)),加入了這個(gè)方法讓代碼復(fù)雜了不少,但是其原理還是很簡(jiǎn)單的:如果當(dāng)前只有一個(gè)線程的話,還不需要?jiǎng)佑肨hreadLocal,直接往firstReaderHoldCount這個(gè)成員變量里存重入數(shù),當(dāng)有第二個(gè)線程來(lái)的時(shí)候,就要?jiǎng)佑肨hreadLocal變量readHolds了,每個(gè)線程擁有自己的副本,用來(lái)保存自己的重入數(shù)

?

protected final boolean tryReleaseShared(int unused) {Thread current = Thread.currentThread();if (firstReader == current) {// assert firstReaderHoldCount > 0;if (firstReaderHoldCount == 1)firstReader = null;elsefirstReaderHoldCount--;} else {HoldCounter rh = cachedHoldCounter;if (rh == null || rh.tid != getThreadId(current))rh = readHolds.get();int count = rh.count;if (count <= 1) {readHolds.remove();if (count <= 0)throw unmatchedUnlockException();}--rh.count;}for (;;) {int c = getState();int nextc = c - SHARED_UNIT;if (compareAndSetState(c, nextc))// Releasing the read lock has no effect on readers,// but it may allow waiting writers to proceed if// both read and write locks are now free.return nextc == 0;}}

?讀鎖的釋放工作,主要是包括更新計(jì)數(shù)器的值(重入次數(shù)),以及更新state(總的讀鎖重入次數(shù))

計(jì)數(shù)器:HoldCounter

在讀鎖的獲取、釋放過(guò)程中,總是會(huì)有一個(gè)對(duì)象存在著,同時(shí)該對(duì)象在獲取線程獲取讀鎖是+1,釋放讀鎖時(shí)-1,該對(duì)象就是HoldCounter

要明白HoldCounter就要先明白讀鎖。前面提過(guò)讀鎖的內(nèi)在實(shí)現(xiàn)機(jī)制就是共享鎖,對(duì)于共享鎖其實(shí)我們可以稍微的認(rèn)為它不是一個(gè)鎖的概念,它更加像一個(gè)計(jì)數(shù)器的概念。一次共享鎖操作就相當(dāng)于一次計(jì)數(shù)器的操作,獲取共享鎖計(jì)數(shù)器+1,釋放共享鎖計(jì)數(shù)器-1。只有當(dāng)線程獲取共享鎖后才能對(duì)共享鎖進(jìn)行釋放、重入操作。所以HoldCounter的作用就是當(dāng)前線程持有共享鎖的數(shù)量,這個(gè)數(shù)量必須要與線程綁定在一起,否則操作其他線程鎖就會(huì)拋出異常。

static final class HoldCounter {int count = 0;final long tid = Thread.currentThread().getId(); }static final class ThreadLocalHoldCounterextends ThreadLocal<HoldCounter> {public HoldCounter initialValue() {return new HoldCounter();} }private transient ThreadLocalHoldCounter readHolds;private transient HoldCounter cachedHoldCounter;

在HoldCounter中僅有count和tid兩個(gè)變量,其中count代表著計(jì)數(shù)器,tid是線程的id。但是如果要將一個(gè)對(duì)象和線程綁定起來(lái)僅記錄tid肯定不夠的,而且HoldCounter根本不能起到綁定對(duì)象的作用,只是記錄線程tid而已

誠(chéng)然,在java中,我們知道如果要將一個(gè)線程和對(duì)象綁定在一起只有ThreadLocal才能實(shí)現(xiàn) 。ThreadLocalHoldCounter繼承ThreadLocal,并且重寫(xiě)了initialValue方法。

故而,HoldCounter應(yīng)該就是綁定線程上的一個(gè)計(jì)數(shù)器,而ThradLocalHoldCounter則是線程綁定的ThreadLocal。從上面我們可以看到ThreadLocal將HoldCounter綁定到當(dāng)前線程上,同時(shí)HoldCounter也持有線程Id,這樣在釋放鎖的時(shí)候才能知道ReadWriteLock里面緩存的上一個(gè)讀取線程(cachedHoldCounter)是否是當(dāng)前線程。這樣做的好處是可以減少ThreadLocal.get()的次數(shù),因?yàn)檫@也是一個(gè)耗時(shí)操作。需要說(shuō)明的是這樣HoldCounter綁定線程id而不綁定線程對(duì)象的原因是避免HoldCounter和ThreadLocal互相綁定而GC難以釋放它們(盡管GC能夠智能的發(fā)現(xiàn)這種引用而回收它們,但是這需要一定的代價(jià)),所以其實(shí)這樣做只是為了幫助GC快速回收對(duì)象而已。

寫(xiě)鎖的獲取與釋放

寫(xiě)鎖的lock和unlock調(diào)用的獨(dú)占式同步狀態(tài)的獲取與釋放,因此真實(shí)的實(shí)現(xiàn)就是Sync的 tryAcquire和 tryRelease。

protected final boolean tryAcquire(int acquires) {Thread current = Thread.currentThread();int c = getState();//寫(xiě)線程數(shù)量(即獲取獨(dú)占鎖的重入數(shù))int w = exclusiveCount(c);//當(dāng)前同步狀態(tài)state != 0,說(shuō)明已經(jīng)有其他線程獲取了讀鎖或?qū)戞iif (c != 0) {// 當(dāng)前state不為0,此時(shí):如果寫(xiě)鎖狀態(tài)為0說(shuō)明讀鎖此時(shí)被占用返回false;// 如果寫(xiě)鎖狀態(tài)不為0且寫(xiě)鎖沒(méi)有被當(dāng)前線程持有返回falseif (w == 0 // w==0 ,說(shuō)明寫(xiě)鎖為0,c!=0 說(shuō)明讀鎖正在操作||current != getExclusiveOwnerThread() // w != 0 說(shuō)明有寫(xiě)鎖在操作,但是不是本線程,則返回false。)return false;//判斷同一線程獲取寫(xiě)鎖是否超過(guò)最大次數(shù)(65535),支持可重入if (w + exclusiveCount(acquires) > MAX_COUNT)throw new Error("Maximum lock count exceeded");//此時(shí)當(dāng)前線程已持有寫(xiě)鎖,現(xiàn)在是重入,所以只需要修改鎖的數(shù)量即可。setState(c + acquires);return true;}//到這里說(shuō)明此時(shí)c=0,讀鎖和寫(xiě)鎖都沒(méi)有被獲取if (writerShouldBlock() //判斷寫(xiě)是否阻塞||!compareAndSetState(c, c + acquires) //競(jìng)爭(zhēng)失敗,)return false;//設(shè)置寫(xiě)鎖為當(dāng)前線程所有setExclusiveOwnerThread(current);return true; }

更新寫(xiě)鎖重入次數(shù)以及state

protected final boolean tryRelease(int releases) {//若鎖的持有者不是當(dāng)前線程,拋出異常if (!isHeldExclusively())throw new IllegalMonitorStateException();//寫(xiě)鎖的新線程數(shù)int nextc = getState() - releases;//如果獨(dú)占模式重入數(shù)為0了,說(shuō)明獨(dú)占模式被釋放boolean free = exclusiveCount(nextc) == 0;if (free)//若寫(xiě)鎖的新線程數(shù)為0,則將鎖的持有者設(shè)置為nullsetExclusiveOwnerThread(null);//設(shè)置寫(xiě)鎖的新線程數(shù)//不管獨(dú)占模式是否被釋放,更新獨(dú)占重入數(shù)setState(nextc);return free; }

公平鎖與非公平鎖

NonfairSync

static final class NonfairSync extends Sync {private static final long serialVersionUID = -8159625535654395037L;final boolean writerShouldBlock() {return false; // writers can always barge}final boolean readerShouldBlock() {return apparentlyFirstQueuedIsExclusive();}}

FairSync

static final class FairSync extends Sync {private static final long serialVersionUID = -2274990926593161451L;final boolean writerShouldBlock() {return hasQueuedPredecessors();}final boolean readerShouldBlock() {return hasQueuedPredecessors();}}

NonFairSync與FairSync的區(qū)別:writerShouldBlock()與readerShouldBlock()方法的實(shí)現(xiàn)不同

readerShouldBlock

  • NonfairSync.readerShouldBlock

?????? 調(diào)用:apparentlyFirstQueuedIsExclusive,如果隊(duì)列中第一個(gè)節(jié)點(diǎn)是獨(dú)占式,則返回true,堵塞讀鎖。

//判斷是否:隊(duì)列中第一個(gè)等待節(jié)點(diǎn)是獨(dú)占模式的final boolean apparentlyFirstQueuedIsExclusive() {Node h, s;return (h = head) != null && //head節(jié)點(diǎn)不為空。(s = h.next) != null && //head的后置節(jié)點(diǎn)不為空!s.isShared() && //head的后置節(jié)點(diǎn)不是共享模式s.thread != null; //head的后置節(jié)點(diǎn)關(guān)聯(lián)了線程。}

調(diào)用apparentlyFirstQueuedIsExclusive方法, 為了防止寫(xiě)線程饑餓等待,如果同步隊(duì)列中的第一個(gè)線程是以獨(dú)占模式獲取鎖(寫(xiě)鎖),那么當(dāng)前獲取讀鎖的線程需要阻塞,讓隊(duì)列中的第一個(gè)線程先執(zhí)行。

  • FairSync.readerShouldBlock

?????? 調(diào)用:hasQueuedPredecessors,判斷是否是等待隊(duì)列中是否有前置節(jié)點(diǎn),有則返回true

writerShouldBlock

  • NonfairSync.writerShouldBlock

?????? 直接返回false,說(shuō)明非公平鎖不堵塞寫(xiě)鎖。

  • FairSync.writerShouldBlock

?????? 調(diào)用:hasQueuedPredecessors,判斷是否是等待隊(duì)列中是否有前置節(jié)點(diǎn),有則返回true

?

?

?

超強(qiáng)干貨來(lái)襲 云風(fēng)專(zhuān)訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生

總結(jié)

以上是生活随笔為你收集整理的ReentrantReadWriteLock源码解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。