Java原子類中CAS的底層實現

來源:互聯網
上載者:User

標籤:for語句   img   exception   返回   thread   輸出時間   圖片   oop   bsp   

Java原子類中CAS的底層實現

從Java到c++到彙編, 深入講解cas的底層原理.

介紹原理前, 先來一個Demo

以AtomicBoolean類為例.先來一個調用cas的demo.

主線程在for語句裡cas忙迴圈, 直到cas操作成功返回true為止.

而新開的一個縣城new Thread 會在4秒後,將flag設定為true, 為了讓主線程能夠設定成功.(因為cas的預期值是true, 而flag被初始化為了false)

現象就是主線程一直在跑for迴圈. 4秒後, 主線程將會設定成功, 然後輸出時間差, 然後終止for迴圈.

public class TestAtomicBoolean {    public static void main(String[] args) {        AtomicBoolean flag = new AtomicBoolean(false);        long start = System.currentTimeMillis();        new Thread(()->{            try {                Thread.sleep(4000);            } catch (InterruptedException e) {                e.printStackTrace();            }            flag.set(true);        }).start();        for(;;){            if(flag.compareAndSet(true,false)){                System.out.println(System.currentTimeMillis() - start);                System.out.println("inner loop OK!");                break;            }        }    }}

這裡只是舉了一個例子, 也許這個例子也不太恰當, 本文只是列出了這個api的調用方法而已, 重點在於介紹compareAndSet()方法的底層原理.

Java級源碼AtomicBoolean.java

發現AtomicBoolean的compareAndSet()調用的是unsafe裡的compareAndSwapInt()方法.

Java級源碼Unsafe.java

有的同學可能好奇, 其中的unsafe是怎麼來的.

在AtomicBoolean類中的靜態成員變數:

如果還要細究Unsafe.getUnsafe()是怎麼實現的話....那麼我再貼一份Unsafe類裡的getUnsafe的代碼:

首先, 在Unsafe類裡, 自己就有了一個自己的執行個體.(單例)

然後Unsafe類裡的getUnsafe()方法會進行檢查, 最終會return這個單例 theUnsafe.

剛剛跑去取介紹了getUnsafe()方法...接下來繼續講解cas...

剛才說到了AtomicBoolean類裡的compareAndSet()方法內部其實調用了Unsafe類裡的compareAndSwapInt()方法.

Unsafe類裡的compareAndSwapInt源碼如下:

(OpenJDK8的源碼裡路徑: openjdk/jdk/src/share/classes/sun/misc/Unsafe.java)

發現這裡是一段native方法.說明繼續看源碼的話, 從這裡就開始脫離Java語言了....

c++級源碼Unsafe.cpp

本源碼在OpenJDK8裡的路徑為: openjdk/hotspot/src/share/vm/prims/unsafe.cpp

(這裡臨時跑題一下:   如果說要細究 UNSAFE_ENTRY 是什麼的話...UNSAFE_ENTRY 就是 JVM_ENTRY, 而 JVM_ENTRY 在interfaceSupport.hpp裡面定義了, jni相關.如果想看的話, 源碼路徑在OpenJDK8中的路徑是這個: 

openjdk/hotspot/src/share/vm/runtime/interfaceSupport.hpp)

回到本文的主題cas....上面的這段代碼, 最後一句是return, 發現其中的使用到的是Atomic下的cmpxchg()方法.

c++級源碼atomic.cpp

本段源碼對應OpenJDK8的路徑是這個: openjdk/hotspot/src/share/vm/runtime/atomic.cpp

其中的cmpxchg為核心內容. 但是這句代碼根據作業系統和處理器的不同, 使用不同的底層代碼. 

而atomic.inline.hpp裡聲明如下:

可見 ...不同不同作業系統, 不同的處理器, 都要走不同的cmpxchg()方法的實現.

咱們接下來以其中的linux作業系統 x86處理器為例 , atomic_linux_x86.inline.hpp

彙編級源碼atomic_linux_x86.inline.hpp

OpenJDK中路徑如下: openjdk/hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp

看到了__asm__, 說明c++要開始內聯彙編了,說明繼續看代碼的話, 將會是組合語言.

這是一段內聯彙編:

 

未完待續....困了睡.....

 

 

 

Java原子類中CAS的底層實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.