日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

三分鐘帶你秒懂CAS實現機制

來源: 責編: 時間:2024-06-06 17:42:08 170觀看
導讀一、摘要在 Java 的java.util.concurrent包中,除了提供底層鎖、并發同步等工具類以外,還提供了一組原子操作類,大多以Atomic開頭,他們位于java.util.concurrent.atomic包下。所謂原子類操作,顧名思義,就是這個操作要么全部

一、摘要

在 Java 的java.util.concurrent包中,除了提供底層鎖、并發同步等工具類以外,還提供了一組原子操作類,大多以Atomic開頭,他們位于java.util.concurrent.atomic包下。RBM28資訊網——每日最新資訊28at.com

所謂原子類操作,顧名思義,就是這個操作要么全部執行成功,要么全部執行失敗,是保證并發編程安全的重要一環。RBM28資訊網——每日最新資訊28at.com

以AtomicInteger原子類為例,應用示例如下!RBM28資訊網——每日最新資訊28at.com

public class Demo {    /**     * 初始化一個原子操作類     */    private static AtomicInteger a = new AtomicInteger();    public static void main(String[] args) throws InterruptedException {        final int threads = 10;        CountDownLatch countDownLatch = new CountDownLatch(threads);        for (int i = 0; i < threads; i++) {            new Thread(new Runnable() {                @Override                public void run() {                    for (int j = 0; j < 1000; j++) {                        // 采用原子性操作累加                        a.incrementAndGet();                    }                    countDownLatch.countDown();                }            }).start();        }        // 阻塞等待10個線程執行完畢        countDownLatch.await();        // 輸出結果值        System.out.println("結果值:" + a.get());    }}

輸出結果:RBM28資訊網——每日最新資訊28at.com

結果值:10000

相比通過synchronized和lock等方式實現的線程安全同步操作,原子類的實現機制則完全不同。它采用的是通過無鎖(lock-free)的方式來實現線程安全(thread-safe)訪問,底層原理主要基于CAS操作來實現。RBM28資訊網——每日最新資訊28at.com

某些業務場景下,通過原子類來操作,既可以實現線程安全的要求,又可以實現高效的并發性能,同時編程方面更加簡單。RBM28資訊網——每日最新資訊28at.com

二、什么是 CAS 操作呢?

CAS,全稱是:Compare and Swap,翻譯過來就是:比較并替換。它是實現并發算法時常用的一種技術,它包含三個操作數:內存位置、預期原值及新值。在執行CAS操作的時候,會將內存位置的值與預期原值比較,如果一致,會將該位置的值更新為新值;否則,不做任何操作。RBM28資訊網——每日最新資訊28at.com

我們還是以AtomicInteger原子類為例,部分源碼內容如下:RBM28資訊網——每日最新資訊28at.com

public class AtomicInteger extends Number implements java.io.Serializable {    private static final long serialVersionUID = 6214790243416807050L;    // 使用 Unsafe.compareAndSwapInt 方法進行 CAS 操作    private static final Unsafe unsafe = Unsafe.getUnsafe();    private static final long valueOffset;    static {        try {            valueOffset = unsafe.objectFieldOffset                (AtomicInteger.class.getDeclaredField("value"));        } catch (Exception ex) { throw new Error(ex); }    }    // 變量使用 volatile 保證可見性    private volatile int value;    /**     * get 方法     */    public final int get() {        return value;    }    /**     * 原子性自增操作     */    public final int incrementAndGet() {        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;    }}

從源碼上可以清晰的看出,變量value使用了volatile關鍵字,保證數據可見性和程序的有序性;原子性自增操作incrementAndGet()方法,路由到Unsafe.getAndAddInt()方法上。RBM28資訊網——每日最新資訊28at.com

我們繼續往下看Unsafe.getAndAddInt()這個方法,部分源碼內容如下:RBM28資訊網——每日最新資訊28at.com

public final class Unsafe {    public final int getAndAddInt(Object var1, long var2, int var4) {        int var5;        // 1.循環比較并替換,只有成功才返回        do {            // 2.調用底層方法得到 value 值            var5 = this.getIntVolatile(var1, var2);            // 3.通過var1和var2得到底層值,var5為當前值,如果底層值與當前值相同,則將值設為var5+var4        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));        // 4.如果替換成功,返回當前值        return var5;    }    /**     * CAS 核心方法,由其他語言實現,不再分析     */    public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);}

從以上的源碼可以清晰的看到,incrementAndGet()方法主要基于Unsafe.compareAndSwapInt方法來實現,同時進行了循環比較與替換的操作,只有替換成功才會返回,這個過程也被稱為自旋操作,確保程序執行成功,進一步保證了操作的原子性。RBM28資訊網——每日最新資訊28at.com

其它的方法實現思路也類似。RBM28資訊網——每日最新資訊28at.com

如果我們自己通過CAS編寫incrementAndGet(),大概長這樣:RBM28資訊網——每日最新資訊28at.com

public int incrementAndGet(AtomicInteger var) {    int prev, next;    do {        prev = var.get();        next = prev + 1;    } while ( !var.compareAndSet(prev, next));    return next;}

當并發數量比較低的時候,采用CAS這種方式可以實現更快的執行效率;當并發數量比較高的時候,因為存在循環比較與替換的邏輯,如果長時間循環,可能會更加消耗 CPU 資源,此時采用synchronized或Lock來實現線程同步,可能會更有優勢。RBM28資訊網——每日最新資訊28at.com

三、ABA問題

從上文的分析中,我們知道 CAS 在操作的時候會檢查預期原值是否發生變化,當預期原值沒有發生變化才會更新值。RBM28資訊網——每日最新資訊28at.com

在實際業務中,可能會出現這么一個現象:線程 t1 正嘗試將共享變量的值 A 進行修改,但還沒修改;此時另一個線程 t2 獲取到 CPU 時間片,將共享變量的值 A 修改成 B,然后又修改為 A,此時線程 t1 檢查發現共享變量的值沒有發生變化,就會主動去更新值,導致出現了錯誤更新,但是實際上原始值在這個過程中發生了好幾次變化。這個現象我們稱它為 ABA 問題。RBM28資訊網——每日最新資訊28at.com

ABA 問題的解決思路就是使用版本號,在變量前面追加上版本號,每次變量更新的時候把版本號加 1,原來的A-B-A就會變成1A-2B-3A。RBM28資訊網——每日最新資訊28at.com

在java.util.concurrent.atomic包下提供了AtomicStampedReference類,它支持指定版本號來更新,可以通過它來解決 ABA 問題。RBM28資訊網——每日最新資訊28at.com

在AtomicStampedReference類的compareAndSet()方法中,會檢查當前引用是否等于預期引用,并且當前版本號是否等于預期版本號,如果全部相等,則以原子方式將該引用的值設置為給定的更新值,同時更新版本號。RBM28資訊網——每日最新資訊28at.com

具體示例如下:RBM28資訊網——每日最新資訊28at.com

// 初始化一個帶版本號的原子操作類,原始值:a,原始版本號:1AtomicStampedReference<String> reference = new AtomicStampedReference<>("a", 1);// 將a更為b,同時將版本號加1,第一個參數:預期原值;第二個參數:更新后的新值;第三個參數:預期原版本號;第四個參數:更新后的版本號boolean result1 = reference.compareAndSet("a", "b", reference.getStamp(), reference.getStamp() + 1);System.out.println("第一次更新:" + result1);// 將b更為a,因為預期原版本號不對,所以更新失敗boolean result2 = reference.compareAndSet("b", "a", 1, reference.getStamp());System.out.println("第二次更新:" + result2);

輸出結果:RBM28資訊網——每日最新資訊28at.com

第一次更新:true第二次更新:false

四、小結

本文主要以AtomicInteger的用法和原理為例,對 CAS 實現原理進行介紹,JUC包下的原子操作類非常的多,但是大體用法和原理基本相似,只是針對不同的數據類型做了細分處理。RBM28資訊網——每日最新資訊28at.com

希望本篇的知識總結,能幫助到大家!RBM28資訊網——每日最新資訊28at.com

五、參考

1.https://www.liaoxuefeng.com/wiki/1252599548343744/1306581083881506RBM28資訊網——每日最新資訊28at.com

2.https://blog.csdn.net/zzti_erlie/article/details/123001758RBM28資訊網——每日最新資訊28at.com

3.https://juejin.cn/post/7057032581165875231RBM28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-92468-0.html三分鐘帶你秒懂CAS實現機制

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 動態鏈接庫的實現原理是什么?

下一篇: 功能問題:如何防止接口重復請求?

標簽:
  • 熱門焦點
  • 28個SpringBoot項目中常用注解,日常開發、求職面試不再懵圈

    前言在使用SpringBoot開發中或者在求職面試中都會使用到很多注解或者問到注解相關的知識。本文主要對一些常用的注解進行了總結,同時也會舉出具體例子,供大家學習和參考。注解
  • 線程通訊的三種方法!通俗易懂

    線程通信是指多個線程之間通過某種機制進行協調和交互,例如,線程等待和通知機制就是線程通訊的主要手段之一。 在 Java 中,線程等待和通知的實現手段有以下幾種方式:Object 類下
  • 讓我們一起聊聊文件的操作

    文件【1】文件是什么?文件是保存數據的地方,是數據源的一種,比如大家經常使用的word文檔、txt文件、excel文件、jpg文件...都是文件。文件最主要的作用就是保存數據,它既可以保
  • JavaScript學習 -AES加密算法

    引言在當今數字化時代,前端應用程序扮演著重要角色,用戶的敏感數據經常在前端進行加密和解密操作。然而,這樣的操作在網絡傳輸和存儲中可能會受到惡意攻擊的威脅。為了確保數據
  • 在線圖片編輯器,支持PSD解析、AI摳圖等

    自從我上次分享一個人開發仿造稿定設計的圖片編輯器到現在,不知不覺已過去一年時間了,期間我經歷了裁員失業、面試找工作碰壁,寒冬下一直沒有很好地履行計劃.....這些就放在日
  • 2天漲粉255萬,又一賽道在抖音爆火

    來源:運營研究社作者 | 張知白編輯 | 楊佩汶設計 | 晏談夢潔這個暑期,旅游賽道徹底火了:有的「地方」火了&mdash;&mdash;貴州村超旅游收入 1 個月超過 12 億;有的「博主」火了&m
  • 華為Mate 60保護殼曝光:碩大后置相機模組 凸起程度有驚喜

    這段時間以來,關于華為新旗艦的爆料日漸密集。據此前多方爆料,今年華為將開始恢復一年雙旗艦戰略,除上半年推出的P60系列外,往年下半年的Mate系列也將
  • 三星推出Galaxy Tab S9系列平板電腦以及Galaxy Watch6系列智能手表

    2023年7月26日,三星電子正式發布了Galaxy Z Flip5與Galaxy Z Fold5。除此之外,Galaxy Tab S9系列平板電腦以及三星Galaxy Watch6系列智能手表也同期
  • OPPO K11評測:旗艦級IMX890加持 2000元檔最強影像手機

    【Techweb評測】中端機型用戶群體巨大,占了中國目前手機市場的大頭,一直以來都是各手機品牌的“必爭之地”,其中OPPO K系列機型一直以來都以高品質、
Top 主站蜘蛛池模板: 永登县| 华容县| 临安市| 绥芬河市| 恩平市| 合川市| 西吉县| 新兴县| 临朐县| 饶河县| 大洼县| 镇巴县| 饶平县| 武宁县| 西乡县| 乐亭县| 电白县| 合川市| 大宁县| 夏河县| 门头沟区| 台前县| 南溪县| 沧源| 中阳县| 舟山市| 铜鼓县| 谷城县| 宜春市| 亳州市| 长泰县| 安义县| 手机| 桃园市| 保亭| 株洲市| 阿合奇县| 中西区| 沂源县| 伊宁县| 淮南市|