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

Java原子變量類常見問題解決

 更新時間:2020年03月13日 10:51:41   作者:yuanyb  
這篇文章主要介紹了Java原子變量類常見問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

在學習多線程時,遇到了原子變量類,它是基于 CAS 和 volatile 實現(xiàn)的,能夠保障對共享變量進行 read-modify-write 更新操作的原子性和可見性。于是我就寫了一段代碼試試,自認為非常正確。

public class Test{
  private static AtomicInteger ID = new AtomicInteger(0);
  public static int nextID(){ //返回的ID范圍為 1~100
    if(ID.get() == 100) { //ID到達100時,則從1開始
      ID.set(1);
      return ID.get(); // return ID = 1;
    }
    else
      return ID.incrementAndGet(); //++ID
  }
  public static void main(String[] args) throws Exception{
    for(int i = 0; i < 5; i++){
      new Thread(()->{
        for(int j = 0; j < 100; j++)
          nextID();
      }).start();
    }
    Thread.sleep(1000); //應(yīng)該輸出100才對
    System.out.println(ID);
  }
}

用五個線程并發(fā)獲得ID,每個線程獲取100個,最后應(yīng)該輸出100才是,但試了好幾次都不是100。原子變量類不是能保障原子性和可見性嗎,為什么出現(xiàn)了競態(tài)?

糾結(jié)了很久,還是很懵逼。后來發(fā)現(xiàn) get 方法相當于讀取一個 volatile 變量,而讀取一個 volatile 變量時,不具備排他性!(AtomicInteger類內(nèi)部使用了volatile修飾了value值,而volatile關(guān)鍵字不具備排他性)

也就是說,當一個線程剛讀取到了共享的 volatile 變量的值時,其他線程可會馬上對共享變量進行修改。如,線程A讀取到ID的值為99時(還沒對ID進行修改),其他線程可能馬上就將ID加1了,此時共享變量為100了,其他線程再獲取ID時,應(yīng)該令I(lǐng)D=1才是,但線程A已經(jīng)進入了else分支,它還認為ID=99,而不知道其他線程剛把ID加1變成了100,所以會吧ID加上1變成了101,這就出現(xiàn)了競態(tài)。

《Java多線程編程實戰(zhàn)指南 - 核心篇》中,作者說:“可見性的保障僅僅意味著一個線程能夠讀取到共享變量的相對新值,而不能保障該線程能讀取到相應(yīng)變量的最新值”。如volatile對可見性的保障就是保障的相對新值,由于volatile不具備排他性,所以有可能讀線程剛讀到一個相對新值,寫線程就更改了共享變量,此時,讀線程剛剛讀取到的相對新值就不是最新的了。

作者對相對新值和最新值的定義:

對于同一個共享變量而言,一個線程更新了該變量的值之后,其他線程能夠讀取到這個更新后的值,那這個值就被稱為該變量的 相對新值。

如果讀取這個共享變量的線程在讀取并使用該變量的時候其他線程無法更新該變量的值,那么該線程讀取到的相對新值就被稱為該變量的 最新值。需要加鎖,才能讀取到最新值。

解決辦法,使用原子操作 compareAndSet:

private static int nextID(){ //返回的ID范圍為 1~100
  ID.compareAndSet(100, 0);
  return ID.incrementAndGet();
}

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java實現(xiàn)查找文件和替換文件內(nèi)容

    Java實現(xiàn)查找文件和替換文件內(nèi)容

    這篇文章主要為大家詳細介紹了Java語言如何實現(xiàn)查找文件和替換文件內(nèi)容功能,文中的示例代碼講解詳細,感興趣的可以跟隨小編一起學習一下
    2022-08-08
  • Java垃圾回收機制算法詳解

    Java垃圾回收機制算法詳解

    這篇文章主要介紹了Java垃圾回收機制算法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • Java并發(fā)LinkedBlockingQueue源碼分析

    Java并發(fā)LinkedBlockingQueue源碼分析

    這篇文章主要為大家介紹了Java并發(fā)LinkedBlockingQueue源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • mybatis 查詢sql中in條件用法詳解(foreach)

    mybatis 查詢sql中in條件用法詳解(foreach)

    這篇文章主要介紹了mybatis 查詢sql中in條件用法詳解(foreach),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 詳解Spring Boot實戰(zhàn)之Filter實現(xiàn)使用JWT進行接口認證

    詳解Spring Boot實戰(zhàn)之Filter實現(xiàn)使用JWT進行接口認證

    本篇文章主要介紹了詳解Spring Boot實戰(zhàn)之Filter實現(xiàn)使用JWT進行接口認證,具有一定的參考價值,有興趣的可以了解一下
    2017-07-07
  • MyBatis 配置之集合的嵌套方式

    MyBatis 配置之集合的嵌套方式

    這篇文章主要介紹了MyBatis 配置之集合的嵌套方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • springboot簡單集成Security配置的教程

    springboot簡單集成Security配置的教程

    這篇文章主要介紹了springboot簡單集成Security配置的教程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • 關(guān)于Java的ArrayList數(shù)組自動擴容機制

    關(guān)于Java的ArrayList數(shù)組自動擴容機制

    這篇文章主要介紹了關(guān)于Java的ArrayList數(shù)組自動擴容機制,ArrayList底層是基于數(shù)組實現(xiàn)的,是一個動態(tài)數(shù)組,自動擴容,不是線程安全的,只能用在單線程環(huán)境下,需要的朋友可以參考下
    2023-05-05
  • Java定時器例子_動力節(jié)點Java學院整理

    Java定時器例子_動力節(jié)點Java學院整理

    本文給大家分享了java定時器例子,非常不錯,具有參考借鑒價值,需要的的朋友參考下吧
    2017-05-05
  • Java中BufferedReader與Scanner讀入的區(qū)別詳解

    Java中BufferedReader與Scanner讀入的區(qū)別詳解

    這篇文章主要介紹了Java中BufferedReader與Scanner讀入的區(qū)別詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10

最新評論

西城区| 原阳县| 驻马店市| 武鸣县| 彭阳县| 依安县| 昌宁县| 苏尼特右旗| 湘阴县| 盐亭县| 榆林市| 穆棱市| 松江区| 峡江县| 龙南县| 益阳市| 峨眉山市| 昌黎县| 新河县| 朝阳县| 通化市| 博乐市| 宁武县| 三原县| 息烽县| 新密市| 宁阳县| 涪陵区| 尉氏县| 遵化市| 通江县| 庆安县| 竹溪县| 洱源县| 黄大仙区| 乌拉特后旗| 富锦市| 色达县| 大荔县| 合川市| 沙坪坝区|