新聞中心
一、讀寫鎖的介紹
上一篇文章:《??年底了我裁完兄弟自己也離職了,復(fù)習(xí)了Java鎖的底層準(zhǔn)備面試...??》,聊了一下java并發(fā)包的公平鎖和非公平鎖。

創(chuàng)新互聯(lián)專注于雙臺子網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供雙臺子營銷型網(wǎng)站建設(shè),雙臺子網(wǎng)站制作、雙臺子網(wǎng)頁設(shè)計(jì)、雙臺子網(wǎng)站官網(wǎng)定制、微信小程序定制開發(fā)服務(wù),打造雙臺子網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供雙臺子網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
這篇文章來聊一下讀寫鎖。所謂的讀寫鎖,就是將一個(gè)鎖拆分為讀鎖和寫鎖兩個(gè)鎖,然后你加鎖的時(shí)候,可以加寫鎖,也可以加讀鎖。如下面代碼所示:
如果有一個(gè)線程加了寫鎖,那么其他線程就不能加寫鎖了,同一時(shí)間只能允許一個(gè)線程加寫鎖。因?yàn)榧恿藢戞i就意味著有人要寫一個(gè)共享數(shù)據(jù),那同時(shí)就不能讓其他人來寫這個(gè)數(shù)據(jù)了。
同時(shí)如果有線程加了寫鎖,其他線程就不能加讀鎖了,因?yàn)榧热欢加腥嗽趯憯?shù)據(jù)了,你其他人當(dāng)然不能來讀數(shù)據(jù)了!
如果有一個(gè)線程加了讀鎖,別的線程是可以隨意同時(shí)加讀鎖的,因?yàn)橹皇怯芯€程在讀數(shù)據(jù)而已,此時(shí)別的線程也是可以來讀數(shù)據(jù)的!
同理,如果一個(gè)線程加了讀鎖,此時(shí)其他線程是不可以加寫鎖的,因?yàn)榧热挥腥嗽谧x數(shù)據(jù),那就不能讓你隨意來寫數(shù)據(jù)了!
好了!這個(gè)就是初步介紹一下讀寫鎖的使用方法,相信很多同學(xué)應(yīng)該之前都知道了,因?yàn)檫@個(gè)是java開發(fā)中非?;A(chǔ)的一塊知識。
二、微服務(wù)注冊中心的讀寫鎖優(yōu)化
現(xiàn)在進(jìn)入主題,我們主要聊一下微服務(wù)注冊中心里面的讀寫鎖優(yōu)化。
為什么要聊一下這個(gè)問題呢?
因?yàn)槿绻愠鋈ッ嬖嚕芸赡鼙粏柕阶x寫鎖的問題,此時(shí)你可以自然而然的帶出來,你之前了解過Spring Cloud微服務(wù)技術(shù)架構(gòu),同時(shí)對里面的微服務(wù)注冊中心的注冊表讀寫鎖優(yōu)化有一些自己的感悟和看法。
這樣的話,相比于你簡單的給面試官聊聊讀寫鎖的基本概念和使用方法,要增色不少!
好,了解了這些前置知識之后,我們正式開始。
先來看看下面的圖,現(xiàn)在我們知道一個(gè)微服務(wù)注冊中心(可以是Eureka或者Consul或者你自己寫的一個(gè)微服務(wù)注冊中心),他肯定會(huì)在內(nèi)存中有一個(gè)服務(wù)注冊表的概念。
這個(gè)服務(wù)注冊表中就是存放了各個(gè)微服務(wù)注冊時(shí)發(fā)送過來的自己的地址信息,里面保存了每個(gè)服務(wù)有多少個(gè)服務(wù)實(shí)例,每個(gè)服務(wù)實(shí)例部署在哪臺機(jī)器上監(jiān)聽哪個(gè)端口號,主要是這樣的一些信息。
OK,那現(xiàn)在問題來了,這個(gè)服務(wù)注冊表的數(shù)據(jù),其實(shí)是有人讀也有人寫的。
舉個(gè)例子,比如有的服務(wù)啟動(dòng)的時(shí)候會(huì)來注冊,此時(shí)就會(huì)修改服務(wù)注冊表的數(shù)據(jù),這個(gè)就是寫的過程。
接著,別的服務(wù)也會(huì)來讀這個(gè)服務(wù)注冊表的數(shù)據(jù),因?yàn)槊總€(gè)服務(wù)都需要感知到其他服務(wù)在哪些機(jī)器上部署。
所以,這個(gè)內(nèi)存里的服務(wù)注冊表數(shù)據(jù),天然就是有讀寫并發(fā)問題的!可能會(huì)有多個(gè)線程來寫,也可能會(huì)有多個(gè)線程來讀!
如果你對同一份內(nèi)存中的注冊表數(shù)據(jù)不加任何保護(hù)措施,那么可能會(huì)有多線程并發(fā)修改共享數(shù)據(jù)的問題,可能導(dǎo)致數(shù)據(jù)錯(cuò)亂,對吧?
上述過程,大家看看下面的圖,就明白了。
此時(shí),如果對服務(wù)注冊表的服務(wù)注冊和讀取服務(wù)注冊表的方法,都加一個(gè)synchronized關(guān)鍵字,是不是就可以了呢?
或許你會(huì)想,加上synchronized,直接讓所有線程對服務(wù)注冊表的讀寫操作,全部串行化。那不就可以保證內(nèi)存中的服務(wù)注冊表數(shù)據(jù)安全了嗎?
下面是一段偽代碼,大家來感受一下:
在上面的代碼中直接給寫(服務(wù)注冊)和讀(讀取服務(wù)注冊表)兩個(gè)方法,都暴力的加上了synchronized關(guān)鍵字,確實(shí)是可以保證服務(wù)注冊表的數(shù)據(jù)不錯(cuò)亂,但是這樣肯定是不太合適的。
因?yàn)檫@么搞的話,相當(dāng)于是所有的線程讀寫服務(wù)注冊表數(shù)據(jù),全部串行化了。
大家思考一下,我們想要的效果是什么?其實(shí)不就是在有人往服務(wù)注冊表里寫數(shù)據(jù)的時(shí)候,就不讓其他人寫了,同時(shí)也不讓其他人讀!
然后,有人在讀服務(wù)注冊表的數(shù)據(jù)的時(shí)候,其他人都可以隨便同時(shí)讀,但是此時(shí)不允許別人寫服務(wù)注冊表數(shù)據(jù)了!
對吧,我們想要的,其實(shí)不就是這個(gè)效果嗎?
想清楚了這點(diǎn),我們就不應(yīng)該暴力的加一個(gè)synchronized,讓所有讀寫線程全部串行化,那樣會(huì)導(dǎo)致并發(fā)性非常的低。
大家看看下面的圖,我們想要的第一個(gè)效果:一旦有人在寫服務(wù)注冊表數(shù)據(jù),我們加個(gè)寫鎖,此時(shí)別人不能寫,也不能讀。
那么如果有人在讀數(shù)據(jù)呢?此時(shí)就可以讓別人都可以讀,但是不允許任何人寫。大家看下面的圖。
關(guān)鍵點(diǎn)來了,這樣做有什么好處呢?其實(shí)大部分時(shí)候都是讀操作,所以使用讀鎖可以讓大量的線程同時(shí)來讀數(shù)據(jù),不需要阻塞不需要排隊(duì),保證高并發(fā)讀的性能是比較高的。
然后?少量的時(shí)候是有服務(wù)上線要注冊數(shù)據(jù),寫數(shù)據(jù)的場景是比較少的,此時(shí)寫數(shù)據(jù)的時(shí)候,只能一個(gè)一個(gè)的加寫鎖然后寫數(shù)據(jù),同時(shí)寫數(shù)據(jù)的時(shí)候就不允許別人來讀數(shù)據(jù)了。
所以讀寫鎖是非常適合這種讀多寫少的場景的。
另外,我們能不能盡量在寫數(shù)據(jù)的期間還保證可以繼續(xù)讀數(shù)據(jù)呢?大量加讀鎖的時(shí)候,會(huì)阻塞人家寫數(shù)據(jù)加寫鎖過長時(shí)間,這種情況能否避免呢?
最后看下上面那段偽代碼如果用讀寫鎖來優(yōu)化是怎么樣的??
新聞名稱:MyBatisPlus聯(lián)表查詢短板有工具補(bǔ)齊了,微服務(wù)架構(gòu)也可以優(yōu)化了
路徑分享:http://www.dlmjj.cn/article/cohecdj.html


咨詢
建站咨詢
