AutomaticInteger中CAS運用分析

摘要

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

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:對象的引用;this

  var2:值的偏移量;spa

       var3:指望值;線程

       var4:更新值;code

       咱們接下來對這個方法的功能解釋一下,這個方法它是一個本地方法,它底層是C++寫的,裏面究竟是什麼你們能夠在網上搜不少資料來查看,這裏我我通俗的給你們說明一下。這個方法的做用就是拿着對象的引用以及位偏移量從內存中拿到值,而後拿着這個值和指望值進行一個比較,若是相同則將要更新的值放到內存中返回true若是不一樣則返回false.說到這裏你們可能就知道這就是一次CAS了,那如今咱們說一下編號爲1的那行代碼是幹嗎的,簡單的來講就是從內存中拿到value值(它到底底層是若是實現的你們也能夠上網上搜搜)。

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

總結

  怎麼說?嗯,由於網上對cas的解釋多的數不勝數因此就沒有再去粘貼和總結那些知識點也請你們多多包涵,對於本文的問題請大夥積極指出我必定研究並修改,但願能互相促進學習。END !

相關文章
相關標籤/搜索