Java CAS操作與Unsafe類詳解
一、復習
計算機內存模型,synchronized和volatile關鍵字簡介
二、兩者對比
sychronized和volatile都解決了內存可見性問題
不同點:
(1)前者是獨占鎖,并且存在者上下文切換的開銷以及線程重新調度的開銷;后者是非阻塞算法,不會造成上下文切換的開銷。
(2)前者可以保證操作的原子性,但是后者不能保證操作的原子性。
三、在什么情況下才會使用volatile
- 寫入變量是不依賴當前值的,如果是依賴當前值的話,由于獲取-計算-寫入,三者不是原子性操作,而volatile是保證原子性操作的。
- 變量沒有加鎖的時候,如果變量加鎖了,是可以保證內存的可見性的因此不需要再使用volatile
四、Java中的原子性操作
- 原子性操作通俗的來講就是一組操作,要么都執(zhí)行成功,要么都執(zhí)行失敗,不存在執(zhí)行部分成功的情況
- 使用synchronized關鍵字既可以保證操作的原子性又可以保證內存的可見性,volatile只能保證內存的可見性,但是不能保證操作的原子性;synchronized固然好,但在高并發(fā)的情況下,由于它是一種獨占鎖,因此會引起性能低下的問題。
五、Java中的CAS操作
- 定義:CAS(compare and swap)比較并交換,這是JDK提供的一種非阻塞算法,它通過硬件保證了比較-更新的原子性問題。JDK中的Unsafe類提供了一系列的compareAndSwap*方法,下面以compareAndSwapLong為例進行講解
- boolean compare(Object obj,long offset,long expect,long update)
- 先分別解釋一下各個參數(shù),obj是一個對象的引用(也就是對象存儲的地址),offset是相對于前面地址的偏移量,expect是一個預想的值,update代表如果和預想的值一樣,那么就是使用update這個值來代替,并且返回true,否則返回false
- 這是處理器提供的一種原子性指令
六、ABA問題
- 描述:線程1獲取變量x的值為A,然后嘗試修改為B,但是此時如果有另一個線程修改了x的值為B,同時又修改成了A,那么線程2的這個A和線程1之前的A就不是同一個A了
- 產(chǎn)生原因:環(huán)形依賴,變量的值從A到B,然后又從B到A,這樣只能一個方向輪轉,如果是從A到B,然后從B到C就不會出現(xiàn)這種情況。
- 解決方式:JDK中的AtomicStampedReferece給每個變量一個時間戳,從而避免了ABA問題
七、Unsafe類
在JDK中的rt.jar包中有許多方法都是native的,這是一種硬件級別的操作,使用JNI來調用C++底層函數(shù)來操作。
1.long objectFieldOffset(Field field)
釋義:獲取某個對象的中的某個域值所在對象的中的內存偏移量
try{
long value = Unsafe.objectFieldOffset(AutomicLong.class.getDeclaredField("value"));
}catch(Exception e){
e.printStackTrace();
}
2.int arrayBaseOffset(Class arrayClass)
釋義:獲取數(shù)組中的第一個元素地址
3.int arrayIndexOffset(Class arrayClass)
釋義:獲取數(shù)組中第一個元素的字節(jié)大小
4.boolean compareAndSwapLong(Object obj,long offset,long expect,long update)
可以見上文
八、源碼:
所在包:com.ruigege.OtherFoundationOfConcurrent2
https://github.com/ruigege66/ConcurrentJava
以上就是Java CAS操作與Unsafe類詳解的詳細內容,更多關于Java CAS操作與Unsafe類的資料請關注腳本之家其它相關文章!
相關文章
Spring的連接數(shù)據(jù)庫以及JDBC模板(實例講解)
下面小編就為大家?guī)硪黄猄pring的連接數(shù)據(jù)庫以及JDBC模板(實例講解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10
Mybatis SqlSessionFactory與SqlSession詳細講解
SqlSessionFactory是MyBatis的核心類之一,其最重要的功能就是提供創(chuàng)建MyBatis的核心接口SqlSession,所以我們需要先創(chuàng)建SqlSessionFactory,為此我們需要提供配置文件和相關的參數(shù)2022-11-11
SpringBoot3實戰(zhàn)教程之實現(xiàn)接口簽名驗證功能
接口簽名是一種重要的安全機制,用于確保 API 請求的真實性、數(shù)據(jù)的完整性以及防止重放攻擊,這篇文章主要介紹了SpringBoot3實戰(zhàn)教程之實現(xiàn)接口簽名驗證功能,需要的朋友可以參考下2025-04-04
SpringBoot-Admin實現(xiàn)微服務監(jiān)控+健康檢查+釘釘告警
本文主要介紹了SpringBoot-Admin實現(xiàn)微服務監(jiān)控+健康檢查+釘釘告警,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10
關于HashMap 并發(fā)時會引起死循環(huán)的問題解析
JDK1.8之前采用頭插,即在鏈表結構上每次都把數(shù)據(jù)放在鏈表頭部。JDK1.8采用尾插方法,很多朋友在學習Java并發(fā)容器和框架時,看到為什么要使用ConcurrentHashMap時不知道究其原因,今天小編通過本文給大家介紹下HashMap 并發(fā)死循環(huán)問題,一起看看吧2021-05-05
Java?Lombok實現(xiàn)手機號碼校驗的示例代碼
手機號碼校驗通常是系統(tǒng)開發(fā)中最基礎的功能之一,本文主要介紹了Java?Lombok實現(xiàn)手機號碼校驗的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-07-07
Mybatis邏輯分頁與物理分頁PageHelper使用解析
這篇文章主要為大家介紹了Mybatis邏輯分頁與物理分頁PageHelper使用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12

