AutomaticInteger中CAS運用分析


摘要

  在接觸CAS的時候雖然對它流程了解了但是對其如何解決並發問題還是一直有疑問的,所以在就選擇了java中典型線程安全的AtomicInteger類進行了源碼的分析。

CAS簡介

  CAS的全稱為compare and swap簡單的解釋為比較交換,這個過程其實是發生在內存中的,應該說是匯編語言的一個操作過程。那么樂觀鎖為什么用CAS算法呢?簡單的來說就是樂觀鎖每次操作的時候都認為不會發生並發,但是為了安全還是會去檢測是否並發了,這樣的話不用sync耗費太大性能

正文

  接下來就開始說正文。我們先從AtomicInteger類的incrementAndGet()的方法解析吧,代碼如下所示:

 public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
 }

  OK,這是一段非常簡單的代碼至於為什么把它拿出來是因為我覺得我有必要湊一下字數不然顯的我寫的第一篇文章實在是太短了。不過這里有個東西我要解釋一下就是這個valueoffset,這個是AtomicInteger中被volatile關鍵字修飾的value在內存中的偏移量,嗯,貼個代碼占點字數。

static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

  可以看出來這個偏移量在類加載過程中就得到了,接下來咱們點擊去getAndAddInt方法內,代碼如下所示:

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

        return var5;
    }

  上面這段代碼就是咱們要說的重點了,先忽略編號為1的代碼,我們先看代號為2的代碼行。方法compareAndSwapInt方法有四個參數,解釋一下:

  var1:對象的引用;

  var2:值的偏移量;

       var3:期望值;

       var4:更新值;

       我們接下來對這個方法的功能解釋一下,這個方法它是一個本地方法,它底層是C++寫的,里面到底是什么大家可以在網上搜很多資料來查看,這里我我通俗的給大家說明一下。這個方法的作用就是拿着對象的引用以及位偏移量從內存中拿到值,然后拿着這個值和期望值進行一個比較,如果相同則將要更新的值放到內存中返回true如果不同則返回false.說到這里大家可能就知道這就是一次CAS了,那現在我們說一下編號為1的那行代碼是干嘛的,簡單的來說就是從內存中拿到value值(它到底底層是如果實現的大家也可以上網上搜搜)。

  好,現在我們就開始解釋一下這個方法,首先從內存中拿到value的值,然后將這個值作為compareAndSwapInt方法的期望值,然后再將對象的引用和值偏移量作為var1參數和var2參數,然后帶上更新值執行compareAndSwapInt方法,之后就是等待返回true和flase然后判斷時候做循環。OK講到這里估計大家就比較清楚了,對於C++里面你是怎么保證原子性的請在百度框搜索"java cas 詳解"。

總結

  怎么說?嗯,因為網上對cas的解釋多的數不勝數所以就沒有再去粘貼和總結那些知識點也請大家多多包涵,對於本文的問題請大伙積極指出我一定研究並修改,希望能互相促進學習。END !


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM