怎么做網(wǎng)站知乎搭建網(wǎng)站需要什么技術(shù)
源于:XX網(wǎng),如果冒犯,表示歉意
面試官:什么是CAS
我:這個簡單,開心鎖
面試官:WTF?
我:一臉自信,對,就是這個
面試官:哈哈大笑,哈哈~ ,回去等通知吧
我:WFT?笑啥呢?
觀眾:下午剛被拒絕,瞬間被你治愈。。抑郁癥都被治好了
CAS含義:
compare and swap,翻譯過來就是比較并替換。內(nèi)存地址V,舊的預(yù)期值A(chǔ),要修改的新值B。俗稱:樂觀鎖
那么樂觀鎖的定義是什么呢?:
樂觀鎖是對于數(shù)據(jù)沖突保持一種樂觀態(tài)度,操作數(shù)據(jù)時不會對操作的數(shù)據(jù)進(jìn)行加鎖(這使得多個任務(wù)可以并行的對數(shù)據(jù)進(jìn)行操作),只有到數(shù)據(jù)提交的時候才通過一種機(jī)制來驗證數(shù)據(jù)是否存在沖突(一般實現(xiàn)方式是通過加版本號然后進(jìn)行版本號的對比方式實現(xiàn));
本質(zhì)上是CPU的一個指令集,能夠提供的一個操作,此操作是不停的for 循環(huán),不停的去用這個指令去獲取某個內(nèi)存的地址,如果獲取到了,則代表獲取到了鎖。
舉個底層源碼的列子AtomicInteger中的方法:
是一個do while循環(huán)的操作,這里有2個操作
1.? v = getIntVolatile(o, offset):
用于獲取對象中偏移地址對應(yīng)的整型的值。其中,o 表示對象,offset 表示偏移量。這個方法會返回共享內(nèi)存中的 value 值,通過 volatile 控制值的可見性,確保從內(nèi)存里拿到的值是當(dāng)前最新的值。
2.?weakCompareAndSetInt(o, offset, v, v + delta)
用于比較內(nèi)存中的值,舊值是否相等,如果相等就把修改后的值寫到內(nèi)存中,返回true。表示修改成功。
其中,o 表示對象,offset 表示偏移量,v 和 v+delta 分別表示期望值和新值(相同就表示這期間沒有其它的線程來修改這個值)。這個方法是原子性的,也就是說在執(zhí)行過程中不會被其他線程打斷。
它的底層是一個Native方法:
英文說明:
如果Java變量當(dāng)前持有預(yù)期值,則自動更新為x。
該操作具有易失性讀寫的內(nèi)存語義。對應(yīng)C11 atomic_compare_exchange_strong(C++)。
返回:
成功則為真
寫了個demo:
1.簡單的進(jìn)行加一,期待值跟實際值的比較
2. 讓2個線程競爭上崗
CAS會產(chǎn)生什么問題:
1.對的,就是你想的那個ABA的問題
解決方式:通過版本號,每次進(jìn)行比較跟交換的時候,比較時間戳/版本號,進(jìn)行比較
2.底層實現(xiàn):是通過while操作不了就一直循環(huán),長時間循環(huán)的話會導(dǎo)致CPU空轉(zhuǎn),消耗資源
解決方式:需要控制自旋次數(shù)
3. 它只能保證一個變量的原子操作,而不能保證一個代碼塊的原子性