欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java多線程場(chǎng)景解析volatile和AtomicLong區(qū)別原理

 更新時(shí)間:2023年09月22日 11:38:46   作者:趙KK日常技術(shù)記錄  
這篇文章主要為大家介紹了Java中volatile和AtomicLong的區(qū)別原理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

【摘要】

隨著多線程編程的普及,volatile和AtomicLong這兩個(gè)關(guān)鍵字被越來(lái)越多的使用。但是很多人并不理解它們的原理以及區(qū)別。今天我就來(lái)通過(guò)一個(gè)典型的場(chǎng)景,講解 volatile 和 AtomicLong 的用法、原理以及區(qū)別,希望可以幫助大家更好地使用這兩者。

我們假設(shè)有這樣一個(gè)多線程場(chǎng)景:存在一個(gè)長(zhǎng)整型變量,多個(gè)線程同時(shí)進(jìn)行讀寫(xiě)操作。為了保證線程安全,我們通常會(huì)進(jìn)行同步,但是同步操作又會(huì)影響效率。這個(gè)時(shí)候我們就可以考慮用 volatile 或者 AtomicLong 來(lái)優(yōu)化。

volatile

先說(shuō)說(shuō) volatile,它可以保證變量的可見(jiàn)性,具體來(lái)說(shuō)就是當(dāng)一個(gè)線程修改了 volatile 變量,新值對(duì)其他線程立即可見(jiàn)。這是因?yàn)関olatile變量直接操作主內(nèi)存,而不是線程的工作內(nèi)存。

java
public class VolatileExample {
  volatile long count = 0;
  public void increment() {
    count++; 
  }
  public long getCount() {
    return count;
  }
}

這里通過(guò) volatile 關(guān)鍵字,可以保證多個(gè)線程都能讀取到 count 的最新的值。但是,volatile 并不能保證原子性。什么意思呢?我們來(lái)看看下面的代碼:

java
public void increment() {
  count++;
}
// 這里的遞增操作并不是原子的,實(shí)際會(huì)分為三步
// 1. 讀取count值 
// 2. 計(jì)算值+1
// 3. 寫(xiě)入新的值

也就是說(shuō)某一個(gè)時(shí)刻,可能有兩個(gè)線程同時(shí)讀取了 count 值,然后分別增加,這就破壞了原子性。要解決這個(gè)問(wèn)題,我們就需要 AtomicLong 了。

AtomicLong

AtomicLong 通過(guò) CAS (Compare And Swap) 算法實(shí)現(xiàn)了對(duì)長(zhǎng)整型的原子操作??匆粋€(gè)例子:

java
AtomicLong atomicCount = new AtomicLong();
public void increment() {
  atomicCount.getAndIncrement(); 
}

getAndIncrement()會(huì)先獲取當(dāng)前的值,然后原子地增加,最后返回舊值。這樣多個(gè)線程調(diào)用的時(shí)候可以保證原子性。AtomicLong 的 CAS 原理是通過(guò)循環(huán)調(diào)用 CAS 指令,直到更新成功為止:

java
do {
  // 獲取舊的預(yù)期值 
  oldValue = atomicCount.get();
  // 用CAS指令更新值,如果預(yù)期值一樣才更新    
  success = compareAndSet(oldValue, oldValue + 1); 
// 如果失敗,繼續(xù)循環(huán)執(zhí)行CAS  
} while(!success);

通過(guò) CAS 不斷嘗試更新,直到成功為止。

volatile 和 AtomicLong 的區(qū)別

總結(jié)一下 volatile 和 AtomicLong 的區(qū)別

1. volatile 保證可見(jiàn)性,AtomicLong 保證原子性

2. volatile 不會(huì)對(duì)代碼產(chǎn)生線程鎖,AtomicLong 會(huì)通過(guò) CAS 產(chǎn)生線程開(kāi)銷

3. volatile 是通過(guò)直接操作主內(nèi)存實(shí)現(xiàn),AtomicLong 是通過(guò) CAS 實(shí)現(xiàn)那么什么時(shí)候該用 volatile,什么時(shí)候該用 AtomicLong 呢?

  • 如果只要保證可見(jiàn)性,那用 volatile 即可。
  • 如果需要原子操作,如對(duì)數(shù)字進(jìn)行遞增操作,這時(shí)就需要用 AtomicLong。

當(dāng)然,synchronized和Lock也能保證原子性,但是通過(guò) CAS 實(shí)現(xiàn)的 AtomicLong 性能會(huì)更好一些。

以上就是本文的全部?jī)?nèi)容了,通過(guò)一個(gè)典型多線程場(chǎng)景講解了 volatile 和 AtomicLong 的用法、原理以及區(qū)別。這兩個(gè)關(guān)鍵字非常有用,正確理解后可以充分利用它們帶來(lái)的優(yōu)勢(shì),更多關(guān)于 Java volatile AtomicLong的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Springboot引入攔截器并放行swagger代碼實(shí)例

    Springboot引入攔截器并放行swagger代碼實(shí)例

    這篇文章主要介紹了Springboot引入攔截器并放行swagger代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Java上傳文件圖片到服務(wù)器的方法

    Java上傳文件圖片到服務(wù)器的方法

    這篇文章主要為大家詳細(xì)介紹了Java上傳文件圖片到服務(wù)器的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • Java中Math.round()的用法及說(shuō)明

    Java中Math.round()的用法及說(shuō)明

    這篇文章主要介紹了Java中Math.round()的用法及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • SpringBoot整合jasypt加密配置文件敏感信息

    SpringBoot整合jasypt加密配置文件敏感信息

    在項(xiàng)目中我們需要對(duì)配置文件的一些敏感信息進(jìn)行加密處理,比如數(shù)據(jù)庫(kù)賬戶密碼,避免直接暴露出來(lái),這種場(chǎng)景常常用于生產(chǎn)環(huán)境,我們不想讓開(kāi)發(fā)人員知道生產(chǎn)庫(kù)的密碼,有運(yùn)維人員統(tǒng)一管理,所以本文給大家介紹了SpringBoot整合jasypt加密配置文件敏感信息
    2024-06-06
  • java類中serialVersionUID的作用及其使用

    java類中serialVersionUID的作用及其使用

    這篇文章主要介紹了java類中serialVersionUID的作用及其使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • java中String字符串刪除空格的七種方式

    java中String字符串刪除空格的七種方式

    在Java中從字符串中刪除空格有很多不同的方法,本文主要介紹了java中String字符串刪除空格的七種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • mybatis解析xml配置中${xxx}占位符的代碼邏輯

    mybatis解析xml配置中${xxx}占位符的代碼邏輯

    本文主要介紹了mybatis解析xml配置中${xxx}占位符的代碼邏輯,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧<BR>
    2023-05-05
  • springboot跨域訪問(wèn)cros與@CrossOrigin注解詳析

    springboot跨域訪問(wèn)cros與@CrossOrigin注解詳析

    這篇文章主要給大家介紹了關(guān)于springboot跨域訪問(wèn)cros與@CrossOrigin注解的相關(guān)資料,跨域是指不同域名之間相互訪問(wèn),它是瀏覽器的同源策略造成的,是瀏覽器對(duì)JavaScript施加的安全限制,需要的朋友可以參考下
    2023-12-12
  • 23種設(shè)計(jì)模式(6)java裝飾者模式

    23種設(shè)計(jì)模式(6)java裝飾者模式

    這篇文章主要為大家詳細(xì)介紹了23種設(shè)計(jì)模式之java裝飾者模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • 10個(gè)SpringBoot參數(shù)驗(yàn)證你需要知道的技巧分享

    10個(gè)SpringBoot參數(shù)驗(yàn)證你需要知道的技巧分享

    參數(shù)驗(yàn)證很重要,是平時(shí)開(kāi)發(fā)環(huán)節(jié)中不可少的一部分,那么在Spring?Boot應(yīng)用中如何做好參數(shù)校驗(yàn)工作呢,本文提供了10個(gè)小技巧,你知道幾個(gè)呢
    2023-03-03

最新評(píng)論