您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關Java中CAS的工作原理是什么,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
1、CAS,compare and swap的縮寫,顧名思義,比較再交換,即 “讀取-修改-寫操作” 三個步驟為一體原子操作;
2、CAS操作包含三個參數:內存位置(V)、預期值(A)、新值(B); 如果內存位置的值V與預期值A相匹配,那么處理器會自動將該位置值更新為新值B,否則不更新;
1、CAS通過JNI方式調用底層操作系統的C代碼,從而借助底層C代碼來調用CPU底層操作指令來實現原子操作;
2、CAS是硬件CPU提供的原語,通過底層cmpxchg原語指令(多處理器再加上Lock指令)實現原子操作;
1、CAS核心源碼:
// Adding a lock prefix to an instruction on MP machine // VC++ doesn't like the lock prefix to be on a single line // so we can't insert a label after the lock prefix. // By emitting a lock prefix, we can define a label after it. #define LOCK_IF_MP(mp) __asm cmp mp, 0 \ __asm je L0 \ __asm _emit 0xF0 \ __asm L0: inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { // alternative for InterlockedCompareExchange int mp = os::is_MP(); __asm { mov edx, dest mov ecx, exchange_value mov eax, compare_value LOCK_IF_MP(mp) // 如果是多處理器的話,則需要添加Lock前綴指令,Lock的方式和Volatile的實現方式雷同 cmpxchg dword ptr [edx], ecx // } }
2、通過上述源碼可以發現該cmpxchg方法會自動判斷當前是否是多處理器,多處理器的話則添加lock前綴指令,反之省略lock前綴;
3、至于lock是怎么保證多處理器的一致性的話,原理和Volatile相似,可見Java技術專題-源碼分析系列(1)volatile工作原理分析雷同。
1、并發操作時,容易引起ABA問題; 假設i初始值i=5,A線程做i++操作一次,B線程做i--操作一次,C線程通過判斷i=5時則對i進行更新新值;
2、這個時候C線程會認為i還是處于初始值,未被做過修改,但是殊不知AB線程已經都對i進行修改了一次;
3、為了解決這種線程,需要讓C知道i已經被修改過了,因此在Java1.5引進了一個AtomicStampedReference類來解決ABA問題;
4、AtomicStampedReference這個類主要是給變量追加了版本號信息,每次變量更新的話版本號都會自增加一;
5、但是有的人會認為AtomicMarkableReference也能解決ABA問題,其實不能根本解決只能在最大程度上降低ABA問題的出現;因為它是通過一個boolean來標記是否更改,本質就是只有true和false兩種版本來回切換,只能降低ABA問題發生的幾率,并不能阻止ABA問題的發生;
1、隨便拿個CAS的Java層代碼:
public final int getAndSetInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var4)); return var5; }
2、通過這段代碼發現,如果CAS操作一直不成功的話,那么該段代碼就一直在自旋操作,會給CPU帶來比較大的執行開銷;
1、目前的CAS只能保證單個共享變量的原子操作;
2、但是對多個變量進行操作時,CAS無法保證,但是可以將多個變量封裝成一個新的對象,利用AtomicReference類來保證引用對象之間的原子性;
1、我們可以在一些非常簡單的操作且又不想引入鎖的場景下采用CAS實現原子操作;
2、然而想要進行非阻塞的完成某些場景也可以考慮采用CAS進行原子操作;
3、但是不推薦在非常復雜的操作中引入CAS,一來會使程序可讀性變差,二來且難以測試且會出現ABA問題。
4、在并發量大且沖突場景非常多的情況,而且如果涉及到代碼塊或者多個變量的原子執行時候,建議不要考慮用CAS。
以上就是Java中CAS的工作原理是什么,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。