天天看點

Java多線程(5):CAS

作者:湘王說

您好,我是湘王,這是我的頭條号「湘王說」,歡迎您來,歡迎您再來~

在JDK1.5之前,Java的多線程都是靠synchronized來保證同步的,這會引起很多性能問題,例如死鎖。但随着Java的不斷完善,JNI(Java Native Interface)使得Java能越過JVM直接調用本地方法,例如CAS。

CAS是Compare And Swap(比較與交換)的縮寫,它用于實作多線程同步的原子指令,允許算法執行讀-修改-寫操作,而無需擔心其他線程同時修改變量。說人話,意思就是它的操作過程足夠細微,以至于線程都奈何不了它。

所謂原子指令就是指不會被線程排程機制打斷的操作指令,這種操作一旦開始,就一直運作到結束,中間不會有任何線程切換,即要麼全部完成,要麼全部中斷。換一種說法,就是CAS可以保證Java運算實作我們想要的操作而無需擔心會受到多線程的影響。

某種程度上,CAS可以用來取代synchronized的強制同步,提升性能。其實整個java.util.concurrent包都是建立在CAS之上的,尤其是Java中大多數鎖的實作基類AbstractQueuedSynchronizer,更是以CAS為基礎,提供了一系列的獨占鎖、共享鎖、可重入鎖、自旋鎖、讀寫鎖等多線程控制手段(這在後面會說)。就像圖中那樣:

Java多線程(5):CAS

Java對CAS的實作都在java.util.concurrent.atomic包下(java.util.concurrent也簡稱JUC,這是個簡稱。是以如果有面試官說想讓你談談JUC相關的問題,不要一臉懵,否則會被立即淘汰)。以AtomicInteger為例,從源碼可以看出CAS操作都是通過sun包下Unsafe類實作,而Unsafe類中的方法都是native方法,由本地實作,和作業系統、CPU都有關系。CAS有一個比較通用的實作模式:

1、首先聲明(共享)變量為volatile

2、然後使用CAS的原子條件來更新

3、同時配合volatile的可見性來實作線程之間的同步

前面講過,不用深究volatile關鍵字的用途,因為随着機器配置的豪華,其實這個關鍵字已經沒啥用了,而且也可以看到,在CAS裡面也有大量出現,JDK已經替你用好了,自己如果不太熟悉就不要用了。CAS相關類結構圖是:

Java多線程(5):CAS

還是老規矩,用代碼來舉例:

Java多線程(5):CAS
Java多線程(5):CAS

CAS的内容并不多,可以看看它的源碼,還是比較有意思的。

感謝您的大駕光臨!咨詢技術、産品、營運和管理相關問題,請關注後留言。歡迎騷擾,不勝榮幸~

我在頭條