做開發(fā),這幾種鎖機制你不得不了解一下
? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ?
摘要:并發(fā)訪問共享資源,如果不加鎖,可能會導(dǎo)致數(shù)據(jù)不一致問題,通常為了解決并發(fā)訪問問題,我們都會在訪問共享資源之前加鎖,保證同一時刻只有一個線程訪問。下面我們用問答的方式說明下各種并發(fā)鎖的概念、優(yōu)缺點及其應(yīng)用場景。
并發(fā)訪問共享資源,如果不加鎖,可能會導(dǎo)致數(shù)據(jù)不一致問題,通常為了解決并發(fā)訪問問題,我們都會在訪問共享資源之前加鎖,保證同一時刻只有一個線程訪問。下面我們用問答的方式說明下各種并發(fā)鎖的概念、優(yōu)缺點及其應(yīng)用場景。
1、什么是互斥鎖和自旋鎖,各有什么優(yōu)缺點?
互斥鎖和自旋鎖是最底層的兩種鎖,其他的很多鎖都是基于他們的實現(xiàn)。當(dāng)線程A獲取到鎖后,線程B再去獲取鎖,有兩種處理方式,第一種是線程B循環(huán)的去嘗試獲取鎖,直到獲取成功為止即自旋鎖,另一種是線程B放棄獲取鎖,在鎖空閑時,等待被喚醒,即互斥鎖。
互斥鎖會釋放當(dāng)前線程的cpu,導(dǎo)致加鎖的代碼阻塞,直到線程再次被喚醒。互斥鎖加鎖失敗時,會從用戶態(tài)陷入到內(nèi)核態(tài),讓內(nèi)核幫我們切換線程,存在一定的性能開銷。
(1)當(dāng)線程加鎖失敗,內(nèi)核會把線程的狀態(tài)由“運行”設(shè)置為“睡眠”,讓出cpu;
(2)當(dāng)鎖空閑時,內(nèi)核喚醒線程,狀態(tài)設(shè)置為“就緒”,獲取cpu執(zhí)行;
而自旋鎖會自用戶態(tài)由應(yīng)用程序完成,不涉及用戶態(tài)到內(nèi)核態(tài)的轉(zhuǎn)化,沒有線程上下文切換,性能相對較好。自旋鎖加鎖過程:
(1)查看鎖的狀態(tài);
(2)鎖空閑,獲取鎖,否則執(zhí)行(1);
自旋鎖會利用cpu一直工作直到獲取到鎖,中間不會釋放cpu,但如果被鎖住的代碼執(zhí)行時間較長,導(dǎo)致cpu空轉(zhuǎn),浪費資源。
2、什么是讀寫鎖?
讀寫鎖由讀鎖和寫鎖組成。讀鎖又稱為共享鎖,S鎖,寫鎖又稱為排它鎖、X鎖,在mysql的事務(wù)中大量使用。寫鎖是獨占鎖,一旦線程獲取寫鎖,其他線程不能獲取寫鎖和讀鎖。
讀鎖是共享鎖,當(dāng)線程獲取讀鎖,其他線程可以獲取讀鎖不能獲取寫鎖。因為并發(fā)數(shù)據(jù)讀取并不會改變共享數(shù)據(jù)導(dǎo)致數(shù)據(jù)不一致。讀寫鎖把對共享資源的讀操作和寫操作分別加鎖控制,能夠提高讀線程的并發(fā)性,適用于讀多寫少的場景。
3、什么是讀優(yōu)先鎖、寫優(yōu)先鎖、公平讀寫鎖?
讀優(yōu)先鎖希望的是讀鎖能夠被更多的線程獲取,可以提高讀線程的并發(fā)性。線程A獲取了讀鎖,線程B想獲取寫鎖,此時會被阻塞,線程c可以繼續(xù)獲取讀鎖,直到A和c釋放鎖,線程B才可以獲取寫鎖。如果有很多線程獲取讀鎖,且加鎖的代碼執(zhí)行時間很長,就到導(dǎo)致線程B永遠(yuǎn)獲取不到寫鎖。
寫優(yōu)先鎖希望的是寫鎖能夠被優(yōu)先獲取。線程A獲取了讀鎖,線程B想獲取寫鎖,此時會被阻塞,后面獲取讀鎖都會失敗,線程A釋放鎖,線程B可以獲取寫鎖,其他獲取讀鎖的線程阻塞。如果有很多寫線程獲取寫鎖,且加鎖的代碼執(zhí)行時間很長,就到導(dǎo)致讀線程永遠(yuǎn)獲取不到讀鎖。
上面兩種鎖都會造成【饑餓】現(xiàn)象,為解決這種問題,可以增加一個隊列,把獲取鎖的線程(不管是寫線程還是讀線程)按照先進(jìn)先出的方式排隊,每次從隊列中取出一個線程獲取鎖,這種獲取鎖的方式是公平的。
4、什么是樂觀鎖和悲觀鎖?
樂觀鎖是先修改共享資源,再用歷史數(shù)據(jù)和當(dāng)前數(shù)據(jù)比對驗證這段時間共享數(shù)據(jù)有沒有被修改,如果沒有被修改,那么更新數(shù)據(jù),如果有其他線程更新了共享資源,需要重新獲取數(shù)據(jù),再更新,驗證,循環(huán)往復(fù)的重試,直到更新成功。所以當(dāng)數(shù)據(jù)更新操作比較頻繁,數(shù)據(jù)沖突的概率就會比較大,重試的次數(shù)就會多,浪費CPU資源。
樂觀鎖其實全程沒有加鎖,也叫無鎖編程,所以針對讀多寫少的場景,并發(fā)性能較高,典型的實現(xiàn)MVCC,mysql中會使用MVCC構(gòu)建一致性讀來保證可重復(fù)讀。悲觀鎖是在訪問共享資源之前統(tǒng)統(tǒng)加鎖。當(dāng)并發(fā)沖突概率較高時,樂觀鎖不在適用,悲觀鎖就排上用場。互斥鎖、自旋鎖都是悲觀鎖的實現(xiàn)。
end
*版權(quán)聲明:轉(zhuǎn)載文章和圖片均來自公開網(wǎng)絡(luò),版權(quán)歸作者本人所有,推送文章除非無法確認(rèn),我們都會注明作者和來源。如果出處有誤或侵犯到原作者權(quán)益,請與我們聯(lián)系刪除或授權(quán)事宜。
長按識別圖中二維碼
關(guān)注獲取更多資訊
不點關(guān)注,我們哪來故事?

點個再看,你最好看
