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

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

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

【摘要】

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

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

volatile

先說說 volatile,它可以保證變量的可見性,具體來說就是當一個線程修改了 volatile 變量,新值對其他線程立即可見。這是因為volatile變量直接操作主內(nèi)存,而不是線程的工作內(nèi)存。

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

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

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

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

AtomicLong

AtomicLong 通過 CAS (Compare And Swap) 算法實現(xiàn)了對長整型的原子操作??匆粋€例子:

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

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

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

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

volatile 和 AtomicLong 的區(qū)別

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

1. volatile 保證可見性,AtomicLong 保證原子性

2. volatile 不會對代碼產(chǎn)生線程鎖,AtomicLong 會通過 CAS 產(chǎn)生線程開銷

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

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

當然,synchronized和Lock也能保證原子性,但是通過 CAS 實現(xiàn)的 AtomicLong 性能會更好一些。

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

相關文章

  • Springboot引入攔截器并放行swagger代碼實例

    Springboot引入攔截器并放行swagger代碼實例

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

    Java上傳文件圖片到服務器的方法

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

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

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

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

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

    java類中serialVersionUID的作用及其使用

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

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

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

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

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

    springboot跨域訪問cros與@CrossOrigin注解詳析

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

    23種設計模式(6)java裝飾者模式

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

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

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

最新評論