樂觀鎖和悲觀鎖
點擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”
優(yōu)質(zhì)文章,第一時間送達(dá)
在多線程場景中,為了保證線程安全,因此需要對線程加鎖,除了使用synchronized關(guān)鍵字外,還有許多的鎖機制。
常見的鎖的類型:
偏向鎖、自旋鎖、輕量級鎖、重量級鎖、獨占鎖、共享鎖、公平鎖、非公平鎖、可重入鎖、讀寫鎖。
樂觀鎖vs悲觀鎖:
樂觀鎖和悲觀鎖只是設(shè)計思想上的一個概念。
樂觀鎖:假設(shè)認(rèn)為數(shù)據(jù)一般情況下不會產(chǎn)生并發(fā)沖突,所以在數(shù)據(jù)提交的時候才會去對數(shù)據(jù)檢查是否發(fā)生了并發(fā)沖突。(即在同一時間點只有一個線程對共享變量操作,所以適合樂觀的思想)
樂觀鎖的問題:并不總是能處理所有問題,所以會引入一定的系統(tǒng)復(fù)雜度。
悲觀鎖:總是假設(shè)最壞的情況,每次別人拿數(shù)據(jù)時都會產(chǎn)生并發(fā)沖突,都會去上鎖。(思想:同一時間點,經(jīng)常有多個線程對共享變量操作,適合悲觀鎖)
悲觀鎖的問題:總是需要競爭鎖,進(jìn)而導(dǎo)致發(fā)生線程切換,掛起其他線程;所以性能不高。
所以要使用哪種設(shè)計思想,應(yīng)該根據(jù)不用的應(yīng)用場景來決定。
基于樂觀鎖實現(xiàn)的機制:CAS機制,又稱無鎖操作;
CAS:Compare And Swap ,比較并交換
CAS(V,O,N)——>V:內(nèi)存地址實際存放的實際值;O:預(yù)期的舊值;N:要賦值的新值。

可能出現(xiàn)的問題:ABA問題
CAS(V,O,N)中,當(dāng)V==O時,N可以直接寫進(jìn)V;當(dāng)N!=O時,不能寫入,但當(dāng)O ==N時,也可能時已經(jīng)被其他線程修改過,但預(yù)期的舊值還是等于主存當(dāng)時存的值,這就是ABA問題。
解決方案:增加版本號;
作用:每次修改后,版本號+1,通過版本號來觀察V是否被修改過。
總結(jié):
1.悲觀鎖是線程先加鎖,后修改變量操作;
2.樂觀鎖是線程直接嘗試修改變量操作,在這個過程中不會發(fā)生線程阻塞;
3. CAS的實現(xiàn)原理:基于unsafe來實現(xiàn),本質(zhì)上是基于CPU提供的接口保證線程安全修改變量;
4. CAS在java中的應(yīng)用:
自旋鎖:
無條件自旋
有條件自旋:如可中斷的自旋(自旋時可以使用線程判斷中斷標(biāo)志位后再執(zhí)行)
自旋+CAS的適用場景:同一時間點,常常只有一個線程操作。
不適用的場景:同一時間點,常常有很多線程操作。
自旋的缺陷:線程一直處于運行狀態(tài),占用CPU內(nèi)存,比較耗費資源。
————————————————
版權(quán)聲明:本文為CSDN博主「AI小艾」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:
https://blog.csdn.net/m0_46551861/article/details/115058433
粉絲福利:Java從入門到入土學(xué)習(xí)路線圖
??????

??長按上方微信二維碼 2 秒
感謝點贊支持下哈 
