最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的CAS鎖機制(無鎖、自旋鎖、樂觀鎖、輕量級鎖)詳解

 更新時間:2024年01月16日 10:54:25   作者:user2025  
這篇文章主要介紹了Java中的CAS鎖機制(無鎖、自旋鎖、樂觀鎖、輕量級鎖)詳解,CAS算法的作用是解決多線程條件下使用鎖造成性能損耗問題的算法,保證了原子性,這個原子操作是由CPU來完成的,需要的朋友可以參考下

什么是CAS機制(compare and swap)

CAS算法的作用:解決多線程條件下使用鎖造成性能損耗問題的算法,保證了原子性,這個原子操作是由CPU來完成的

CAS的原理:CAS算法有三個操作數(shù),通過內(nèi)存中的值(V)、預期原始值(A)、修改后的新值。

(1)如果內(nèi)存中的值和預期原始值相等, 就將修改后的新值保存到內(nèi)存中。

(2)如果內(nèi)存中的值和預期原始值不相等,說明共享數(shù)據(jù)已經(jīng)被修改,放棄已經(jīng)所做的操作,然后重新執(zhí)行剛才的操作,直到重試成功。

注意:

(1)預期原始值(A)是從偏移位置讀取到三級緩存中讓CPU處理的值,修改后的新值是預期原始值經(jīng)CPU處理暫時存儲在CPU的三級緩存中的值,而內(nèi)存指定偏移位置中的原始值。

(2)比較從指定偏移位置讀取到緩存的值與指定內(nèi)存偏移位置的值是否相等,如果相等則修改指定內(nèi)存偏移位置的值,這個操作是操作系統(tǒng)底層匯編的一個原子指令實現(xiàn)的,保證了原子性

  • JVM中CAS是通過UnSafe類來調(diào)用操作系統(tǒng)底層的CAS指令實現(xiàn)。
  • CAS基于樂觀鎖思想來設計的,其不會引發(fā)阻塞,synchronize會導致阻塞。

原子類

java.util.concurrent.atomic包下的原子類都使用了CAS算法。而java.util.concurrent中的大多數(shù)類的實現(xiàn)都直接或間接的使用了這些原子類。 Unsafe類使Java擁有了類似C語言指針操作內(nèi)存空間的能力,同時也帶來了指針的安全問題。

AtomicInteger原子類

AtomicInteger等原子類沒有使用synchronized鎖,而是通過volatile和CAS(Compare And Swap)解決資源的線程安全問題。

(1)volatile保證了可見性和有序性

(2)CAS保證了原子性,而且是無鎖操作,提高了并發(fā)效率。

//創(chuàng)建Unsafe類的實例
private static final Unsafe unsafe = Unsafe.getUnsafe();
//成員變量value是在內(nèi)存地址中距離當前對象首地址的偏移量, 具體賦值是在下面的靜態(tài)代碼塊中中進行的
private static final long valueOffset;
static {
    try {
        //類加載的時候,在靜態(tài)代碼塊中獲取變量value的偏移量
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
    } catch (Exception ex) { throw new Error(ex); }
}
// 當前AtomicInteger原子類的value值
private volatile int value;
//類似于i++操作
public final int getAndIncrement() {
	//this代表當前AtomicInteger類型的對象,valueOffset表示value成員變量的偏移量
    return unsafe.getAndAddInt(this, valueOffset, 1);
}
================================上方為AtomicInteger類中的方法,下方為Unsafe類中的方法=========================================================
//此方法的作用:獲取內(nèi)存地址為原子對象首地址+原子對象value屬性地址偏移量, 并將該變量值加上delta
public final int getAndAddInt(Object obj, long offset, int delta) {
    int v;
    do {
    	//通過對象和偏移量獲取變量值作為期望值,在修改該內(nèi)存偏移位置的值時與原始進行比較
    	//此方法中采用volatile的底層原理,保證了內(nèi)存可見性,所有線程都從內(nèi)存中獲取變量vlaue的值,所有線程看到的值一致。
        v= this.getIntVolatile(obj, offset);
    /*
	while中的compareAndSwapInt()方法嘗試修改v的值,具體地, 該方法也會通過obj和offset獲取變量的值
	如果這個值和v不一樣, 說明其他線程修改了obj+offset地址處的值, 此時compareAndSwapInt()返回false, 繼續(xù)循環(huán)
	如果這個值和v一樣, 說明沒有其他線程修改obj+offset地址處的值, 此時可以將obj+offset地址處的值改為v+delta, compareAndSwapInt()返回true, 退出循環(huán)
	Unsafe類中的compareAndSwapInt()方法是原子操作, 所以compareAndSwapInt()修改obj+offset地址處的值的時候不會被其他線程中斷
	*/
    } while(!this.compareAndSwapInt(obj, offset, v, v + delta));
    return v;
}

操作步驟:

(1)獲取AtomicInteger對象首地址指定偏移量位置上的值,作為期望值。

(2)取出獲取AtomicInteger對象偏移量上的值,判斷與期望值是否相等,相等就修改AtomicInteger在內(nèi)存偏移量上的值,不相等就返回false,重新執(zhí)行第一步操作,重新獲取內(nèi)存指定偏移量位置的值。

(3) 如果相等,則修改值并返回true。

注意:從1、2步可以看CAS機制實現(xiàn)的鎖是自旋鎖,如果線程一直無法獲取到鎖,則一直自旋,不會阻塞

CAS和syncronized的比較

CAS線程不會阻塞,線程一致自旋 syncronized會阻塞線程,會進行線程的上下文切換,會由用戶態(tài)切換到內(nèi)核態(tài),切換前需要保存用戶態(tài)的上下文,而內(nèi)核態(tài)恢復到用戶態(tài),又需要恢復保存的上下文,非常消耗資源。

CAS的缺點

(1)ABA問題 如果一個線程t1正修改共享變量的值A,但還沒修改,此時另一個線程t2獲取到CPU時間片,將共享變量的值A修改為B,然后又修改為A,此時線程t1檢查發(fā)現(xiàn)共享變量的值沒有發(fā)生變化,但是實際上卻變化了。

解決辦法: 使用版本號,在變量前面追加上版本號,每次變量更新的時候把版本號加1,那么A-B-A 就會變成1A-2B-3A。從Java1.5開始JUC包里提供了一個類AtomicStampedReference來解決ABA問題。AtomicStampedReference類的compareAndSet方法作用是首先檢查當前引用是否等于預期引用,并且當前版本號是否等于預期版本號,如果全部相等,則以原子方式將該引用和該標志的值設置為給定的更新值。

(2)循環(huán)時間長開銷會比較大:自旋重試時間,會給CPU帶來非常大的執(zhí)行開銷

(3)只能保證一個共享變量的原子操作,不能保證同時對多個變量的原子性操作 解決辦法: 從Java1.5開始JDK提供了AtomicReference類來保證引用對象之間的原子性,你可以把多個變量放在一個對象里來進行CAS操作

CAS使用注意事項

(1)CAS需要和volatile配合使用

CAS只能保證變量的原子性,不能保證變量的內(nèi)存可見性。CAS獲取共享變量的值時,需要和volatile配合使用,來保證共享變量的可見性

(2)CAS適用于并發(fā)量不高、多核CPU的情況

CPU多核情況下可以同時執(zhí)行,如果不合適就失敗。而并發(fā)量過高,會導致自旋重試耗費大量的CPU資源

到此這篇關于Java中的CAS鎖機制(無鎖、自旋鎖、樂觀鎖、輕量級鎖)詳解的文章就介紹到這了,更多相關CAS鎖機制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java線程的異常處理機制詳情

    Java線程的異常處理機制詳情

    這篇文章主要介紹了Java線程的異常處理機制詳情,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • Java設計模式之單例模式詳解

    Java設計模式之單例模式詳解

    這篇文章主要為大家詳細介紹了Java設計模式之單例模式的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • 詳解Java中的ForkJoin

    詳解Java中的ForkJoin

    Fork/Join框架是Java 7提供的一種用于并行執(zhí)行任務的框架,它將大任務分解為若干個小任務,并行執(zhí)行這些小任務,最終通過合并每個小任務的結(jié)果得到大任務的結(jié)果,文中有詳細的代碼示例,需要的朋友可以參考下
    2023-05-05
  • spring mvc中直接注入的HttpServletRequst安全嗎

    spring mvc中直接注入的HttpServletRequst安全嗎

    這篇文章主要給大家介紹了關于spring mvc中直接注入的HttpServletRequst是不是安全的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起看看吧。
    2018-04-04
  • springBoot使用mybatis-plus插件實現(xiàn)分頁過程

    springBoot使用mybatis-plus插件實現(xiàn)分頁過程

    本文介紹了MyBatisPlus的集成步驟,包括項目結(jié)構(gòu)調(diào)整、pom.xml依賴添加、MyBatisPlusConfig配置文件創(chuàng)建與配置、具體代碼實現(xiàn)(controller、service、dao、xml)、SQL結(jié)果打印、自定義分頁等環(huán)節(jié),此經(jīng)驗總結(jié)供讀者參考學習
    2026-04-04
  • 微服務SpringBoot整合Jasypt加密工具的場景分析

    微服務SpringBoot整合Jasypt加密工具的場景分析

    Jasypt是Java加密工具包,能支持對密碼的哈希加密,對文本和二進制數(shù)據(jù)的對稱加解密,還能集成SpringBoot項目對配置文件中的密鑰進行加密存儲,這篇文章主要介紹了微服務SpringBoot整合Jasypt加密工具,需要的朋友可以參考下
    2022-10-10
  • SpringBoot解析JSON報錯400 Bad Request的解決方案

    SpringBoot解析JSON報錯400 Bad Request的解決方案

    在Spring Boot開發(fā)中,400 Bad Request錯誤是常見的客戶端錯誤之一,本文將從問題分析,排查步驟到解決方案進行系統(tǒng)性講解,幫助開發(fā)者高效定位并修復問題
    2025-07-07
  • Feign遠程調(diào)用丟失請求頭問題

    Feign遠程調(diào)用丟失請求頭問題

    本文介紹了在服務端項目中如何解決資源訪問限制問題,首先介紹了問題的產(chǎn)生,然后詳細解析了源碼,最后提出了解決方案,解決方案包括同步和異步兩種,同步時直接向Spring容器注入RequestInterceptor攔截器
    2024-09-09
  • Redisson分布式鎖的源碼解讀分享

    Redisson分布式鎖的源碼解讀分享

    Redisson是一個在Redis的基礎上實現(xiàn)的Java駐內(nèi)存數(shù)據(jù)網(wǎng)格(In-Memory?Data?Grid)。Redisson有一樣功能是可重入的分布式鎖。本文來討論一下這個功能的特點以及源碼分析
    2022-11-11
  • Java反射機制用法總結(jié)

    Java反射機制用法總結(jié)

    反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為java語言的反射機制。下面我們來一起學習一下吧
    2019-05-05

最新評論

龙井市| 临沧市| 疏勒县| 光泽县| 娄底市| 平度市| 大新县| 潜山县| 积石山| 溆浦县| 承德市| 沂源县| 昂仁县| 太仓市| 镇雄县| 元氏县| 祁东县| 裕民县| 凤城市| 仪征市| 正安县| 呼和浩特市| 德化县| 祁门县| 罗江县| 太原市| 庆元县| 黄浦区| 六安市| 分宜县| 江津市| 沂水县| 金沙县| 衡南县| 玉环县| 波密县| 定陶县| 彩票| 平舆县| 东海县| 吴旗县|