做網(wǎng)站與網(wǎng)店運(yùn)營(yíng)如何免費(fèi)創(chuàng)建自己的網(wǎng)站平臺(tái)
一、ABA問(wèn)題的解決方案
變量第一次讀取的值是1,后來(lái)其他線程改成了3,然后又被其他線程修改成了1,原來(lái)期望的值是第一個(gè)1才會(huì)設(shè)置新值,第二個(gè)1跟期望不符合,但是,可以設(shè)置新值。
解決方案:
(a)增加一個(gè)自定義的版本號(hào)變量,記錄修改日志,每次修改一次,就加1 。當(dāng)值相同時(shí),還要比較版本號(hào),如果版本號(hào)也一樣,才能更新成新的值。
(b)采用原子引用類 AtomicStampedReference,通過(guò)控制變量值的版本號(hào),來(lái)確保CAS的正確性,比較兩個(gè)值引用是否一致,只有一致才會(huì)更新成新值。
二、無(wú)限循環(huán)問(wèn)題(自旋)的解決方案
底層使用一個(gè)while循環(huán)來(lái)實(shí)現(xiàn)的,所以Atomic類設(shè)置值進(jìn)入一個(gè)無(wú)限循環(huán),只要失敗了就不停的循環(huán),再次瘋狂的嘗試。高并發(fā)場(chǎng)景下,多個(gè)線程頻繁修改同一個(gè)值,則會(huì)導(dǎo)致大量線程執(zhí)行compareAndSet的方法時(shí),要循環(huán) n 次才能更新成功,就是大量線程執(zhí)行一個(gè)重復(fù)的空循環(huán)(自旋鎖),造成系統(tǒng)的大量開(kāi)銷。
解決方案:
(a)采用 jdk 8 中的 LongAdder,分段CAS + 自動(dòng)分段遷移。
三、多原子的變量問(wèn)題的解決方案
一般的Atomic類,只能保證一個(gè)共享變量的原子性。
解決方案:
(a)采用 java 并發(fā)包的 AtomicReference,這個(gè)是封裝自定義對(duì)象的,多個(gè)變量可放一個(gè)自定義對(duì)象中,然后它會(huì)檢查該對(duì)象的引用是否是相同。如果多個(gè)線程,同時(shí)對(duì)一個(gè)對(duì)象變量的引用進(jìn)行修改,AtomicReference 的 CAS 算法可解決并發(fā)沖突問(wèn)題。