Java并發(fā)編程ReentrantReadWriteLock加讀鎖流程_第1頁
Java并發(fā)編程ReentrantReadWriteLock加讀鎖流程_第2頁
Java并發(fā)編程ReentrantReadWriteLock加讀鎖流程_第3頁
Java并發(fā)編程ReentrantReadWriteLock加讀鎖流程_第4頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第Java并發(fā)編程ReentrantReadWriteLock加讀鎖流程目錄正文屬性介紹加鎖成功處理

正文

protectedfinalinttryAcquireShared(intunused){

Threadcurrent=Thread.currentThread();

intc=getState();

if(exclusiveCount(c)!=0

getExclusiveOwnerThread()!=current)

return-1;

intr=sharedCount(c);

if(!readerShouldBlock()

rMAX_COUNT

compareAndSetState(c,c+SHARED_UNIT)){

if(r==0){

firstReader=current;

firstReaderHoldCount=1;

}elseif(firstReader==current){

firstReaderHoldCount++;

}else{

HoldCounterrh=cachedHoldCounter;

if(rh==null||rh.tid!=getThreadId(current))

cachedHoldCounter=rh=readHolds.get();

elseif(rh.count==0)

readHolds.set(rh);

rh.count++;

return1;

returnfullTryAcquireShared(current);

上面是嘗試加讀鎖流程的代碼,既然這篇是番外篇,那就不按正常流程一點(diǎn)一點(diǎn)去分析了,著重拿出一部分來分析一下。ReentrantReadWriteLock和ReentrantLock相比,除了多了讀寫鎖之外,還增加了很多屬性,比如firstReader、firstReaderHoldCount、cachedHoldCounter......那我們這篇文章就介紹一下這些新屬性的含義以及上面代碼中加鎖成功后的處理。

屬性介紹

staticfinalclassHoldCounter{

intcount=0;

finallongtid=getThreadId(Thread.currentThread());

HoldCount類型用來存儲(chǔ)線程ID和線程持有的讀鎖數(shù)量

privatetransientThreadLocalHoldCounterreadHolds;

staticfinalclassThreadLocalHoldCounter

extendsThreadLocalHoldCounter{

publicHoldCounterinitialValue(){

returnnewHoldCounter();

readHolds通過ThreadLocal在線程本地存儲(chǔ)了一個(gè)HoldCounter對(duì)象,表示當(dāng)前線程持有的讀鎖重入數(shù)量,主要是為了方便在發(fā)生重入或者釋放鎖時(shí),分別計(jì)算每個(gè)線程持有的讀鎖數(shù)量。

privatetransientHoldCountercachedHoldCounter;

cachedHoldCounter存儲(chǔ)的是最后一個(gè)獲取讀鎖成功的線程持有的讀鎖數(shù)量。但是如果只有一個(gè)線程獲取讀鎖,會(huì)使用firstReader和firstReaderHoldCount來記錄線程持有讀鎖數(shù)量,只有獲取讀鎖的線程數(shù)大于1時(shí)才會(huì)用cachedHoldCounter存儲(chǔ)最后線程持有的讀鎖數(shù)量。

privatetransientThreadfirstReader=null;

第一個(gè)獲取讀鎖的線程,確切地說是把讀鎖數(shù)量從0改成1的線程,并且當(dāng)前還沒有釋放鎖。如果第一個(gè)線程釋放了鎖,就會(huì)把firstReader設(shè)為null,只有當(dāng)所有讀鎖釋放之后,下一個(gè)獲取讀鎖成功的線程就成為firstReader。

privatetransientintfirstReaderHoldCount;

第一個(gè)獲取讀鎖的線程持有讀鎖的數(shù)量。

加鎖成功處理

intr=sharedCount(c);

if(r==0){

firstReader=current;

firstReaderHoldCount=1;

}elseif(firstReader==current){

firstReaderHoldCount++;

}else{

HoldCounterrh=cachedHoldCounter;

if(rh==null||rh.tid!=getThreadId(current))

cachedHoldCounter=rh=readHolds.get();

elseif(rh.count==0)

readHolds.set(rh);

rh.count++;

這里截取加鎖成功之后處理的代碼來分析下對(duì)這些屬性的操作。

if(r==0)表示共享鎖數(shù)量為0,當(dāng)前線程就是第一個(gè)獲取讀鎖成功的線程,所以firstReader和firstReaderHoldCount記錄的就是當(dāng)前線程。如果讀鎖數(shù)量不是0,但是當(dāng)前線程是第一個(gè)線程,那就直接在原來數(shù)量基礎(chǔ)上進(jìn)行累加firstReaderHoldCount++;如果讀鎖數(shù)量不為0,而且當(dāng)前線程也不是第一個(gè)線程,這時(shí)就需要用到cachedHoldCounter了。rh==null表示當(dāng)前線程是第二個(gè)線程,rh.tid!=getThreadId(current)表示當(dāng)前線程至少是第三個(gè)線程(這里不考慮重入情況,只考慮當(dāng)前線程第一次獲取讀鎖成功),兩個(gè)條件合起來可以理解為之前緩存的最后一個(gè)獲取讀鎖成功的線程不是當(dāng)前線程,所以就需要更新為當(dāng)前線程cachedHoldCounter=rh=readHolds.get()。如果之前緩存的最后一個(gè)線程是當(dāng)前線程,那么就會(huì)有一個(gè)特殊情況rh.count==0,這里可以理解為一個(gè)線程釋放了讀鎖之后又重新獲取了讀鎖,釋放完所有鎖時(shí),為了防止內(nèi)存泄漏會(huì)調(diào)用readHolds.remove()清除線程本地存儲(chǔ)的信息,而現(xiàn)在

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論