【面試題】能聊聊你對CAS的理解以及其底層實現原理可以嗎?
當多個執行緒要訪問同一個資料時,包括取值、詢問、修改時,必然會出現多執行緒併發安全問題
public class MyObject{
int i = 0;
public synchronized void increment(){
//同一時間,只有一個執行緒可以進入當前方法
//在一個物件例項的方法上加synchronized
i++;
}
}
呼叫:
MyObject mo = new MyObject();
mo.increment();
這種加鎖的方式是序列化,執行效率不高。多執行緒情況下,需要排隊執行increment方法
使用併發包下的AtomicInteger類(底層基於CAS來進行實現)
public class MyObject{
AtomicInteger i = new AtomicInteger(0);
public void increment(){
//多個執行緒此時來執行這段程式碼
//不需要synchronized加鎖,也是執行緒安全的
i.incrementAndGet();
}
}
CAS全稱 compare and set,CAS操作是原子的,底層會進行硬體之別的上鎖,中間是不可以被打斷的
(1)先讀取當前值,假設i=0
(2)i++
(3)嘗試設定i=1:先對比預期值是否為0,如果為0則設定i=1;
cas(v,expected,newValue)
if(v==expected)
v = newValue;
執行緒1與執行緒2同時呼叫incrementAndSet方法,只有一個執行緒能完成CAS。
CAS在底層的硬體級別保證一定是原子的,同一時間只有一個執行緒可以執行CAS,先比較再設定,其他執行緒的CAS同時間去執行,此時會失敗。
假設:執行緒1成功CAS,執行緒2在CAS過程中發現值不對,會重新讀取當前值,再次嘗試CAS
AtomicXX類底層的實現原理實際上是CAS
【評論區】
CAS雖然高效的解決了原子操作問題,但仍然存在三大問題
1.ABA問題:如果變數V初次讀取的時候值是A,後來變成了B,然後又變成了A,你本來期望的值是第一個A才會設定新值,第二個A跟期望不符合,但卻也能設定新值。針對這種情況,java併發包中提供了一個帶有標記的原子引用類AtomicStampedReference,它可以通過控制變數值的版本號來保證CAS的正確性,比較兩個值的引用是否一致,如果一致,才會設定新值。但使用AtomicStampedReference就可以很好的解決這個問題。
2.無限迴圈問題(自旋):看原始碼可知,Atomic類設定值的時候會進入一個無限迴圈,只要不成功,就會不停的迴圈再次嘗試。在高併發時,如果大量執行緒頻繁修改同一個值,可能會導致大量執行緒執行compareAndSet()方法時需要迴圈N次才能設定成功,即大量執行緒執行一個重複的空迴圈(自旋),造成大量開銷。解決無限迴圈問題可以使用java8中的LongAdder,分段CAS和自動分段遷移。
3.多變數原子問題:只能保證一個共享變數的原子操作。一般的Atomic類,只能保證一個變數的原子性,但如果是多個變數呢?可以用AtomicReference,這個是封裝自定義物件的,多個變數可以放一個自定義物件裡,然後他會檢查這個物件的引用是不是同一個。如果多個執行緒同時對一個物件變數的引用進行賦值,用AtomicReference的CAS操作可以解決併發衝突問題。 但是如果遇到ABA問題,AtomicReference就無能為力了,需要使用AtomicStampedReference來解決。
相關文章
- CAS底層原理與ABA問題
- CAS你知道嗎?底層如何實現?ABA問題又是什麼?關於這些你知道答案嗎
- 七、真正的技術——CAS操作原理、實現、底層原始碼原始碼
- 詳解鎖原理,synchronized、volatile+cas底層實現synchronized
- 面試官:說說反射的底層實現原理?面試反射
- 面試必問:HashMap 底層實現原理分析面試HashMap
- 面試題深入解析:Synchronized底層實現面試題synchronized
- ArrayList底層的實現原理
- HashMap底層實現原理HashMap
- NSDictionary底層實現原理
- AutoreleasePool底層實現原理
- 深入理解Java中的底層阻塞原理及實現Java
- 基礎篇:詳解鎖原理,volatile+cas、synchronized的底層實現synchronized
- MySQL Join的底層實現原理MySql
- MySQL索引底層實現原理MySql索引
- HashMap的實現原理 HashMap底層實現,hashCode如何對應bucket?HashMap
- 【Java】手把手理解CAS實現原理Java
- 「Java」手把手理解CAS實現原理Java
- 理解PHP底層原理(一)PHP
- 初步理解 JavaScript 底層原理JavaScript
- Java I/O模型及其底層原理Java模型
- 底層原理面試彙總面試
- Category:從底層原理研究到面試題分析Go面試題
- 5道面試題,拿捏String底層原理!面試題
- KVO的使用和底層實現原理
- 深入理解 MySQL 底層實現MySql
- 【面試普通人VS高手系列】ConcurrentHashMap 底層具體實現知道嗎?實現原理是什麼?面試HashMap
- 死磕Synchronized底層實現,面試你還怕什麼?synchronized面試
- 以 DEBUG 方式深入理解執行緒的底層執行原理執行緒
- 面試官: 有了解過ReentrantLock的底層實現嗎?說說看面試ReentrantLock
- MG--探究KVO的底層實現原理
- 聊聊keep-alive元件的使用及其實現原理Keep-Alive元件
- 理解https中的安全及其實現原理HTTP
- 徹底理解閉包實現原理
- 【AQS面試篇】瞭解ReentrantLock嗎?講講其底層實現AQS面試ReentrantLock
- 面試:你可以實現一下vue的v-model嗎?面試Vue
- php底層原理之陣列實現PHP陣列
- javascript事件機制底層實現原理JavaScript事件