91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2020-09-08 11:07:05 來源:腳本之家 閱讀:145 作者:yuanyb 欄目:編程語言

在學習多線程時,遇到了原子變量類,它是基于 CAS 和 volatile 實現的,能夠保障對共享變量進行 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); //應該輸出100才對
    System.out.println(ID);
  }
}

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

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

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

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

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

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

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

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

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

沈阳市| 开封市| 奎屯市| 集安市| 陆河县| 咸丰县| 襄樊市| 孝昌县| 益阳市| 池州市| 锡林郭勒盟| 隆林| 渭南市| 蒙阴县| 抚松县| 神木县| 永州市| 普兰店市| 中超| 兴国县| 晋州市| 扎赉特旗| 连平县| 黑水县| 彭阳县| 收藏| 平泉县| 南靖县| 南城县| 罗源县| 荆州市| 湘潭县| 五常市| 嘉义县| 六盘水市| 丹巴县| 缙云县| 汽车| 贺州市| 土默特左旗| 高雄市|