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