版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第Java中讀寫(xiě)鎖ReadWriteLock的原理與應(yīng)用詳解目錄什么是讀寫(xiě)鎖?為什么需要讀寫(xiě)鎖?讀寫(xiě)鎖的特點(diǎn)讀寫(xiě)鎖的使用場(chǎng)景讀寫(xiě)鎖的主要成員和結(jié)構(gòu)圖讀寫(xiě)鎖的實(shí)現(xiàn)原理讀寫(xiě)鎖總結(jié)Java并發(fā)編程提供了讀寫(xiě)鎖,主要用于讀多寫(xiě)少的場(chǎng)景,今天我就重點(diǎn)來(lái)講解讀寫(xiě)鎖的底層實(shí)現(xiàn)原理
什么是讀寫(xiě)鎖?
讀寫(xiě)鎖并不是JAVA所特有的讀寫(xiě)鎖(Readers-WriterLock)顧名思義是一把鎖分為兩部分:讀鎖和寫(xiě)鎖,其中讀鎖允許多個(gè)線(xiàn)程同時(shí)獲得,因?yàn)樽x操作本身是線(xiàn)程安全的,而寫(xiě)鎖則是互斥鎖,不允許多個(gè)線(xiàn)程同時(shí)獲得寫(xiě)鎖,并且寫(xiě)操作和讀操作也是互斥的。
所謂的讀寫(xiě)鎖(Readers-WriterLock),顧名思義就是將一個(gè)鎖拆分為讀鎖和寫(xiě)鎖兩個(gè)鎖。
其中讀鎖允許多個(gè)線(xiàn)程同時(shí)獲得,而寫(xiě)鎖則是互斥鎖,不允許多個(gè)線(xiàn)程同時(shí)獲得寫(xiě)鎖,并且寫(xiě)操作和讀操作也是互斥的。
為什么需要讀寫(xiě)鎖?
Synchronized和ReentrantLock都是獨(dú)占鎖,即在同一時(shí)刻只有一個(gè)線(xiàn)程獲取到鎖。
然而在有些業(yè)務(wù)場(chǎng)景中,我們大多在讀取數(shù)據(jù),很少寫(xiě)入數(shù)據(jù),這種情況下,如果仍使用獨(dú)占鎖,效率將及其低下。
針對(duì)這種情況,Java提供了讀寫(xiě)鎖ReentrantReadWriteLock。
主要解決:對(duì)共享資源有讀和寫(xiě)的操作,且寫(xiě)操作沒(méi)有讀操作那么頻繁的場(chǎng)景。
讀寫(xiě)鎖的特點(diǎn)
公平性:讀寫(xiě)鎖支持非公平和公平的鎖獲取方式,非公平鎖的吞吐量?jī)?yōu)于公平鎖的吞吐量,默認(rèn)構(gòu)造的是非公平鎖可重入:在線(xiàn)程獲取讀鎖之后能夠再次獲取讀鎖,但是不能獲取寫(xiě)鎖,而線(xiàn)程在獲取寫(xiě)鎖之后能夠再次獲取寫(xiě)鎖,同時(shí)也能獲取讀鎖鎖降級(jí):線(xiàn)程獲取寫(xiě)鎖之后獲取讀鎖,再釋放寫(xiě)鎖,這樣實(shí)現(xiàn)了寫(xiě)鎖變?yōu)樽x鎖,也叫鎖降級(jí)
讀寫(xiě)鎖的使用場(chǎng)景
ReentrantReadWriteLock適合讀多寫(xiě)少的場(chǎng)景:
讀鎖ReentrantReadWriteLock.ReadLock可以被多個(gè)線(xiàn)程同時(shí)持有,所以并發(fā)能力很高。
寫(xiě)鎖ReentrantReadWriteLock.WriteLock是獨(dú)占鎖,在一個(gè)線(xiàn)程持有寫(xiě)鎖時(shí)候,其他線(xiàn)程都不能在搶占,包含搶占讀鎖都會(huì)阻塞。
ReentrantReadWriteLock的使用場(chǎng)景總結(jié):其實(shí)就是讀讀并發(fā)、讀寫(xiě)互斥、寫(xiě)寫(xiě)互斥而已,如果一個(gè)對(duì)象并發(fā)讀的場(chǎng)景大于并發(fā)寫(xiě)的場(chǎng)景,那就可以使用ReentrantReadWriteLock來(lái)達(dá)到保證線(xiàn)程安全的前提下提高并發(fā)效率。
讀寫(xiě)鎖的主要成員和結(jié)構(gòu)圖
1.ReentrantReadWriteLock的繼承關(guān)系
publicinterfaceReadWriteLock{
*Returnsthelockusedforreading.
*@returnthelockusedforreading.
LockreadLock();
*Returnsthelockusedforwriting.
*@returnthelockusedforwriting.
LockwriteLock();
}
讀寫(xiě)鎖ReadWriteLock
讀寫(xiě)鎖維護(hù)了一對(duì)相關(guān)的鎖,一個(gè)用于只讀操作,一個(gè)用于寫(xiě)入操作。
只要沒(méi)有寫(xiě)入,讀取鎖可以由多個(gè)讀線(xiàn)程同時(shí)保持,寫(xiě)入鎖是獨(dú)占的。
2.ReentrantReadWriteLock的核心變量
ReentrantReadWriteLock類(lèi)包含三個(gè)核心變量:
ReaderLock:讀鎖,實(shí)現(xiàn)了Lock接口WriterLock:寫(xiě)鎖,也實(shí)現(xiàn)了Lock接口Sync:繼承自AbstractQueuedSynchronize(AQS),可以為公平鎖FairSync或非公平鎖NonfairSync
3.ReentrantReadWriteLock的成員變量和構(gòu)造函數(shù)
/**內(nèi)部提供的讀鎖*/
privatefinalReentrantReadWriteLock.ReadLockreaderLock;
/**內(nèi)部提供的寫(xiě)鎖*/
privatefinalReentrantReadWriteLock.WriteLockwriterLock;
/**AQS來(lái)實(shí)現(xiàn)的同步器*/
finalSyncsync;
*Createsanew{@codeReentrantReadWriteLock}with
*默認(rèn)創(chuàng)建非公平的讀寫(xiě)鎖
publicReentrantReadWriteLock(){
this(false);
*Createsanew{@codeReentrantReadWriteLock}with
*thegivenfairnesspolicy.
*@paramfair{@codetrue}ifthislockshoulduseafairorderingpolicy
publicReentrantReadWriteLock(booleanfair){
sync=fairnewFairSync():newNonfairSync();
readerLock=newReadLock(this);
writerLock=newWriteLock(this);
}
讀寫(xiě)鎖的實(shí)現(xiàn)原理
ReentrantReadWriteLock實(shí)現(xiàn)關(guān)鍵點(diǎn),主要包括:
讀寫(xiě)狀態(tài)的設(shè)計(jì)寫(xiě)鎖的獲取與釋放讀鎖的獲取與釋放鎖降級(jí)
1.讀寫(xiě)狀態(tài)的設(shè)計(jì)
之前談ReentrantLock的時(shí)候,Sync類(lèi)是繼承于AQS,主要以intstate為線(xiàn)程鎖狀態(tài),0表示沒(méi)有被線(xiàn)程占用,1表示已經(jīng)有線(xiàn)程占用。
同樣ReentrantReadWriteLock也是繼承于AQS來(lái)實(shí)現(xiàn)同步,那intstate怎樣同時(shí)來(lái)區(qū)分讀鎖和寫(xiě)鎖的?
如果在一個(gè)整型變量上維護(hù)多種狀態(tài),就一定需要按位切割使用這個(gè)變量,ReentrantReadWriteLock將int類(lèi)型的state將變量切割成兩部分:
高16位記錄讀鎖狀態(tài)低16位記錄寫(xiě)鎖狀態(tài)
abstractstaticclassSyncextendsAbstractQueuedSynchronizer{
//版本序列號(hào)
privatestaticfinallongserialVersionUID=6317671515068378041L;
//高16位為讀鎖,低16位為寫(xiě)鎖
staticfinalintSHARED_SHIFT=16;
//讀鎖單位
staticfinalintSHARED_UNIT=(1SHARED_SHIFT);
//讀鎖最大數(shù)量
staticfinalintMAX_COUNT=(1SHARED_SHIFT)-1;
//寫(xiě)鎖最大數(shù)量
staticfinalintEXCLUSIVE_MASK=(1SHARED_SHIFT)-1;
//本地線(xiàn)程計(jì)數(shù)器
privatetransientThreadLocalHoldCounterreadHolds;
//緩存的計(jì)數(shù)器
privatetransientHoldCountercachedHoldCounter;
//第一個(gè)讀線(xiàn)程
privatetransientThreadfirstReader=null;
//第一個(gè)讀線(xiàn)程的計(jì)數(shù)
privatetransientintfirstReaderHoldCount;
}
2.寫(xiě)鎖的獲取與釋放
protectedfinalbooleantryAcquire(intacquires){
*Walkthrough:
*1.Ifreadcountnonzeroorwritecountnonzero
*andownerisadifferentthread,fail.
*2.Ifcountwouldsaturate,fail.(Thiscanonly
*happenifcountisalreadynonzero.)
*3.Otherwise,thisthreadiseligibleforlockif
*itiseitherareentrantacquireor
*queuepolicyallowsit.Ifso,updatestate
*andsetowner.
Threadcurrent=Thread.currentThread();
intc=getState();
//獲取獨(dú)占鎖(寫(xiě)鎖)的被獲取的數(shù)量
intw=exclusiveCount(c);
if(c!=0){
//(Note:ifc!=0andw==0thensharedcount!=0)
//1.如果同步狀態(tài)不為0,且寫(xiě)狀態(tài)為0,則表示當(dāng)前同步狀態(tài)被讀鎖獲取
//2.或者當(dāng)前擁有寫(xiě)鎖的線(xiàn)程不是當(dāng)前線(xiàn)程
if(w==0||current!=getExclusiveOwnerThread())
returnfalse;
if(w+exclusiveCount(acquires)MAX_COUNT)
thrownewError("Maximumlockcountexceeded");
//Reentrantacquire
setState(c+acquires);
returntrue;
if(writerShouldBlock()||
!compareAndSetState(c,c+acquires))
returnfalse;
setExclusiveOwnerThread(current);
returntrue;
}
1)c是獲取當(dāng)前鎖狀態(tài),w是獲取寫(xiě)鎖的狀態(tài)。
2)如果鎖狀態(tài)不為零,而寫(xiě)鎖的狀態(tài)為0,則表示讀鎖狀態(tài)不為0,所以當(dāng)前線(xiàn)程不能獲取寫(xiě)鎖?;蛘哝i狀態(tài)不為零,而寫(xiě)鎖的狀態(tài)也不為0,但是獲取寫(xiě)鎖的線(xiàn)程不是當(dāng)前線(xiàn)程,則當(dāng)前線(xiàn)程不能獲取寫(xiě)鎖。
3)寫(xiě)鎖是一個(gè)可重入的排它鎖,在獲取同步狀態(tài)時(shí),增加了一個(gè)讀鎖是否存在的判斷。
寫(xiě)鎖的釋放與ReentrantLock的釋放過(guò)程類(lèi)似,每次釋放將寫(xiě)狀態(tài)減1,直到寫(xiě)狀態(tài)為0時(shí),才表示該寫(xiě)鎖被釋放了。
3.讀鎖的獲取與釋放
protectedfinalinttryAcquireShared(intunused){
for(;;){
intc=getState();
intnextc=c+(116);
if(nextcc){
thrownewError("Maxumumlockcountexceeded");
if(exclusiveCount(c)!=0owner!=Thread.currentThread())
return-1;
if(compareAndSetState(c,nextc))
return1;
}
1)讀鎖是一個(gè)支持重進(jìn)入的共享鎖,可以被多個(gè)線(xiàn)程同時(shí)獲取。
2)在沒(méi)有寫(xiě)狀態(tài)為0時(shí),讀鎖總會(huì)被成功獲取,而所做的也只是增加讀狀態(tài)(線(xiàn)程安全)
3)讀狀態(tài)是所有線(xiàn)程獲取讀鎖次數(shù)的總和,而每個(gè)線(xiàn)程各自獲取讀鎖的次數(shù)只能選擇保存在ThreadLocal中,由線(xiàn)程自身維護(hù)。
讀鎖的每次釋放均減小狀態(tài)(線(xiàn)程安全的,可能有多個(gè)讀線(xiàn)程同時(shí)釋放鎖),減小的值是116。
4.鎖降級(jí)
降級(jí)是指當(dāng)前把持住寫(xiě)鎖,再獲取到讀鎖,隨后釋放(先前擁有的)寫(xiě)鎖的過(guò)程。
鎖降級(jí)過(guò)程中的讀鎖的獲取是否有必要,答案是必要的。主要是為了保證數(shù)據(jù)的可見(jiàn)性,如果當(dāng)前線(xiàn)程不獲取讀鎖而直接釋放寫(xiě)鎖,假設(shè)此刻另一個(gè)線(xiàn)程獲取的寫(xiě)鎖,并修改了數(shù)據(jù),那么當(dāng)前線(xiàn)程就步伐感知到線(xiàn)程T的數(shù)據(jù)更新,如果當(dāng)前線(xiàn)程遵循鎖降級(jí)的步驟,那么線(xiàn)程
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年【就業(yè)】上海市第一社會(huì)福利院招聘養(yǎng)老護(hù)理員備考題庫(kù)及參考答案詳解1套
- 2026年九江市專(zhuān)業(yè)森林消防支隊(duì)(九江市綜合應(yīng)急救援支隊(duì))招聘10人備考題庫(kù)完整答案詳解
- 2026年中鐵工程設(shè)計(jì)咨詢(xún)集團(tuán)有限公司社會(huì)招聘?jìng)淇碱}庫(kù)及答案詳解一套
- 2026年中交海峰風(fēng)電發(fā)展股份有限公司招聘?jìng)淇碱}庫(kù)帶答案詳解
- 2026年中國(guó)特種飛行器研究所招聘?jìng)淇碱}庫(kù)及一套完整答案詳解
- 2026年平果市協(xié)力初級(jí)中學(xué)教師招聘?jìng)淇碱}庫(kù)及參考答案詳解
- 2026年關(guān)于龍江縣第一人民醫(yī)院公開(kāi)招聘編外醫(yī)生的備考題庫(kù)及參考答案詳解
- 2026年南海區(qū)大瀝鎮(zhèn)漖表小學(xué)臨聘教師招聘?jìng)淇碱}庫(kù)及答案詳解一套
- 2026年賓陽(yáng)縣祥盛人力資源管理有限公司招聘?jìng)淇碱}庫(kù)及參考答案詳解一套
- 2026年中電建生態(tài)環(huán)境集團(tuán)有限公司招聘?jìng)淇碱}庫(kù)含答案詳解
- 四川省瀘州市2026屆數(shù)學(xué)高二上期末統(tǒng)考試題含解析
- 中國(guó)金融電子化集團(tuán)有限公司2026年度校園招聘?jìng)淇碱}庫(kù)及一套完整答案詳解
- 生物實(shí)驗(yàn)探究教學(xué)中學(xué)生實(shí)驗(yàn)探究能力培養(yǎng)與評(píng)價(jià)體系研究教學(xué)研究課題報(bào)告
- 2025年塔吊指揮員考試題及答案
- 2025福建閩投永安抽水蓄能有限公司招聘21人備考題庫(kù)附答案
- 11116《機(jī)電控制工程基礎(chǔ)》國(guó)家開(kāi)放大學(xué)期末考試題庫(kù)
- 2025四川綿陽(yáng)市江油鴻飛投資(集團(tuán))有限公司招聘40人筆試考試備考題庫(kù)及答案解析
- 雨課堂在線(xiàn)學(xué)堂《社會(huì)研究方法》作業(yè)單元考核答案
- 高中歷史選修一 第13課 當(dāng)代中國(guó)的民族政策 教學(xué)設(shè)計(jì)
- 畢業(yè)設(shè)計(jì)論文晉華宮礦340萬(wàn)噸新井通風(fēng)設(shè)計(jì)含全套CAD圖紙
- 醫(yī)院清洗服務(wù)方案
評(píng)論
0/150
提交評(píng)論