亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

Java多線程CAS操作原理代碼實例解析

瀏覽:3日期:2022-08-28 10:47:20

CAS操作號稱無鎖優化,也叫作自旋;對于一些常見的操作需要加鎖,然后jdk就提供了一些以Atomic開頭的類,這些類內部自動帶了鎖,當然這里的鎖并非是用synchronized來實現的,而是通過CAS操作來實現的;

一、下面是 AtomicInteger 的使用:

package com.designmodal.design.juc01;import java.util.ArrayList;import java.util.List;import java.util.concurrent.atomic.AtomicInteger;/** * @author D-L * @Classname T03_AtomicInteger * @Version 1.0 * @Description 使用 AtomicInteger 類解決常見的 多線程count++ *其內部使用了CAS操作來保證原子性 但是不能保證多個方法連續調用都是原子性 * @Date 2020/7/21 0:35 */public class T03_AtomicInteger { //使用AtomicInteger類 AtomicInteger count = new AtomicInteger(0); public void m(){ for (int i = 0; i < 10000; i++) { //等同于 在 count++ 上加鎖 count.incrementAndGet(); } } public static void main(String[] args) { T03_AtomicInteger t = new T03_AtomicInteger(); List<Thread> threads = new ArrayList<>(); for (int i = 0; i < 10; i++) { threads.add(new Thread(t::m , 'Thread' + i)); } threads.forEach((o) -> o.start()); threads.forEach(o ->{ try {o.join(); } catch (InterruptedException e) {e.printStackTrace(); } }); System.out.println(t.count); }}

二、當然達到使用的級別很簡單,看一下API就好了,通過上面的小程序,下面主要來聊一聊原理:

1、通過源碼分析AtomicInteger

首先小程序中定義了一個 AtomicInteger 類型的變量count;

AtomicInteger count = new AtomicInteger(0); public void add(){ count.incrementAndGet(); }

調用了AtomicInteger類中incrementAndGet();

/** * Atomically increments by one the current value. * * @return the updated value */ public final int incrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, 1) + 1; }

調用unsafe類中的 getAndAddInt(Object var1, long var2, int var4)方法;

public native int getIntVolatile(Object var1, long var2);public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5); public final int getAndAddInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; }

這里通過以上三步的操作,最終會進入Unsafe類這里調用的 compareAndSwapInt 意思就是比較然后交換,通過一個while循環,在這里轉呀轉,直到修改成功;

CAS(compareAndSwap)(比較并交換):原來想改變的值為0 ,現在想修改成1 ,這里想做到線程安全就必須要加synchronized,現在想用另外一種方式來替換加鎖的方法,就是所謂的CAS操作;你可以把它想象成擁有三個參數的方法cas(V , Expected , NewValue); 第一個參數V是你要改的那個值,Expected第二個參數是你期望當前的值是多少(也就是如果沒有線程修改的時,這個值應該是多少,如果不是期望值那就證明有別的線程修改過),NewValue是要設置的新值;

Java多線程CAS操作原理代碼實例解析

上圖簡單模擬了CAS操作的過程,當線程1和線程2同時讀取了共享變量count = 0;在線程1修改的過程中,線程2已經將count值修改為1,那么在線程1修改的時候發現Expected值和V已經匹配不上了,證明已經有線程快我一步將count值改了(可能這里并發量大的時候已經有n多個線程已經修改過了),怎么辦呢?那我只能將我的期望值修改成V的值、newValue 在這基礎上加1,然后繼續在這自旋操作,直到修改成功,這就是自旋操作;

2、Unsafe類(java并發包底層實現的核心)

CAS操作不需要加鎖是如何做到的呢?原因就在于Unsafe這個類,這個類除了你使用反射之外,你是不能夠直接使用的,這里不能使用的原因和ClassLoader有關系,所有AtomicXXX 類內部都是CompareAndSwap / CompareAndSet(新版jdk),這個類中存在好多native方法;

Unsafe類使Java擁有了像C語言的指針一樣操作內存空間的能力,一旦能夠直接操作內存,這也就意味著(1)不受JVM管理,也就意味著無法被GC,需要我們手動GC,稍有不慎就會出現內存泄漏。(2)Unsafe的不少方法中必須提供原始地址(內存地址)和被替換對象的地址,偏移量要自己計算,一旦出現問題就是JVM崩潰級別的異常,會導致整個JVM實例崩潰,表現為應用程序直接crash掉。(3)直接操作內存,也意味著其速度更快,在高并發的條件之下能夠很好地提高效率。

CAS:CompareAndSwap,內存偏移地址(var2),預期值(var4),新值(var5)。如果變量在當前時刻的值和預期值expected相等,嘗試將變量的值更新為新值(var5)。如果更新成功,返回true;否則,返回false。

/** * CAS操作 :Unsafe類中的本地方法 由于Java語言無法訪問操作系統底層信息(比如:底層硬件設備等), * 這時候就需要借助C C++語言來完成了 * @param var1 對象 * @param var2 偏移量 * @param var4 期望值 * @param var5 新值 * @return 修改成功返回true 失敗返回false */ public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5); public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5); public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);

三、CAS操作帶來的ABA問題

ABA問題說白了就是在線程進行CAS操作過程中有多個線程對這個共享變量進行修改,有加有減,兜兜轉轉又回到起始值,這時該線程渾然不知;打個不恰當的比喻:這個過程就好像你前女友跟你分手以后,在時隔一年之后又找你復合來了,說兜兜轉轉還是覺得你好,在此期間你前女友已經換了幾個男朋友你卻渾然不知,那個好看的她穿著你喜歡的小短裙,扎著清純的馬尾辮又回來,好了言歸正傳,意思就是結果是你期望的,可是這個值是經過很多版本的。

下面簡單模擬ABA操作圖:

Java多線程CAS操作原理代碼實例解析

如何解決ABA問題呢?

如果是int類型,最終的值也是你期望的,真的是沒有所謂,你也不用去糾結這問題;如果你確實就想管一管,那就加一個版本號,做一次修改操作加一,比較檢查時連帶版本號一起檢查。

基礎類型:沒有必要管,對你真的沒有所謂;

引用類型:就像是你女朋友和你分手之后又復合,中間經歷了多少個男朋友,這個是有所謂的,這時可以通過加版本號來解決;

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
主站蜘蛛池模板: 亚洲三级黄色片 | 国产精品色婷婷在线观看 | 九九99精品 | 草草影院一级毛片a级 | 国产美女一级高清免费观看 | 精品一区二区三区在线成人 | 婷婷国产偷v国产偷v亚洲 | 伊人久久综合成人亚洲 | 中文字幕无线码欧美成人 | 三级全黄在线观看www桃花 | 日韩一区二区国色天香 | 国产在线观看网址你懂得 | 日韩中文字幕视频在线 | 九九在线偷拍视频在线播放 | 最新内地三级在线观看 | 一区二区三区四区视频在线观看 | 最新在线观看精品国产福利片 | 一级做α爱过程免费视频 | 欧美日韩在线精品成人综合网 | 国产精品yjizz视频网一二区 | 亚洲色图18p | 婷婷色站 | 精品一区二区三区在线播放 | 日本在线网站 | 亚洲伊人精品综合在合线 | 亚洲小younv另类 | 亚洲综合男人的天堂色婷婷 | 成人丝袜激情一区二区 | 午夜影院啪啪 | 国产午夜毛片一区二区三区 | 欧美日产欧美日产精品 | 国产小视频在线播放 | 小馒头刚发育在线播放free | 奇米色88欧美一区二区 | 一级黄色大片免费观看 | 久久久久久久久66精品片 | 尤物视频在线观看网址 | 精品视频在线观看一区二区 | 九九精品影院 | 久久夜色撩人精品国产 | 一97日本道伊人久久综合影院 |