日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java并发_volatile实现可见性但不保证原子性

發布時間:2025/7/14 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java并发_volatile实现可见性但不保证原子性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
讀后感
  • 介紹了volatile實現可見性的基本原理
  • 介紹了volatile不能實現原子性的示例,volatile復合操作不能實現原子性,讀取值后在自增前改值可能被其它線程讀取并修改,自增后刷新值可能會覆蓋其它線程修改后的值
  • 介紹了實現原子性的三種方法及示例
  • synchronized ?修飾對象
  • ReentrantLock 使用lock()、unlock()加鎖解鎖,比synchronized功能更多,JDK6后性能和synchronized差不多
  • AtomicInteger ?使用樂觀鎖


  • ??volatile關鍵字:

    • 能夠保證volatile變量的可見性
    • 不能保證volatile變量復合操作的原子性

    ??volatile如何實現內存可見性:

    ???????? 深入來說:通過加入內存屏障和禁止重排序優化來實現的。

    • 對volatile變量執行寫操作時,會在寫操作后加入一條store屏障指令
    • 對volatile變量執行讀操作時,會在讀操作前加入一條load屏障指令

    ???????? 通俗地講:volatile變量在每次被線程訪問時,都強迫從主內存中重讀該變量的值,而當該變量發生變化時,又會強迫線程將最新的值刷新到主內存。這樣任何時刻,不同的線程總能看到該變量的最新值。

    ?

    ?????????線程寫volatile變量的過程:

    • 改變線程工作內存中volatile變量副本的值
    • 將改變后的副本的值從工作內存刷新到主內存

    ?????????線程讀volatile變量的過程:

    • 從主內存中讀取volatile變量的最新值到線程的工作內存中
    • 從工作內存中讀取volatile變量的副本

    ?????????volatile不能保證volatile變量復合操作的原子性:

    Java代碼??
  • private?int?number?=?0;??
  • number++;?//不是原子操作??
  • ???????? 它分為三步:
    ???????? 讀取number的值
    ???????? 將number的值加1
    ???????? 寫入最新的number的值

    ?

    ??????????保證number自增操作的原子性:

    • 使用synchronized關鍵字
    • 使用ReentrantLock
    • 使用AtomicInteger

    ??????????使用synchronized關鍵字

    Java代碼??
  • import?java.util.concurrent.ExecutorService;??
  • import?java.util.concurrent.Executors;??
  • ??
  • /**?
  • ?*?@author?InJavaWeTrust?
  • ?*/??
  • public?class?TestSyn?implements?Runnable?{??
  • ??
  • ????private?int?number?=?0;??
  • ??
  • ????public?int?getNumber()?{??
  • ????????return?this.number;??
  • ????}??
  • ??
  • ????public?void?run()?{??
  • ????????increase();??
  • ????}??
  • ??
  • ????public?void?increase()?{??
  • ????????synchronized?(this)?{??
  • ????????????this.number++;??
  • ????????}??
  • ????}??
  • ??
  • ????public?static?void?main(String[]?args)?{??
  • ????????ExecutorService?exec?=?Executors.newFixedThreadPool(1000);??
  • ????????TestSyn?syn?=?new?TestSyn();??
  • ????????for?(int?i?=?0;?i?<?1000;?i++)?{??
  • ????????????exec.submit(syn);??
  • ????????}??
  • ????????System.out.println("number?:?"?+?syn.getNumber());??
  • ????????exec.shutdown();??
  • ????}??
  • }??
  • ?

    ??????????使用ReentrantLock

    Java代碼??
  • import?java.util.concurrent.ExecutorService;??
  • import?java.util.concurrent.Executors;??
  • import?java.util.concurrent.locks.Lock;??
  • import?java.util.concurrent.locks.ReentrantLock;??
  • /**?
  • ?*?@author?InJavaWeTrust?
  • ?*/??
  • public?class?TestRee?implements?Runnable?{??
  • ??
  • ????private?Lock?lock?=?new?ReentrantLock();??
  • ????private?int?number?=?0;??
  • ??
  • ????public?int?getNumber()?{??
  • ????????return?this.number;??
  • ????}??
  • ??
  • ????public?void?run()?{??
  • ????????increase();??
  • ????}??
  • ??
  • ????public?void?increase()?{??
  • ????????lock.lock();??
  • ????????try?{??
  • ????????????this.number++;??
  • ????????}?finally?{??
  • ????????????lock.unlock();??
  • ????????}??
  • ????}??
  • ??
  • ????public?static?void?main(String[]?args)?{??
  • ????????TestRee?ree?=?new?TestRee();??
  • ????????ExecutorService?exec?=?Executors.newFixedThreadPool(1000);??
  • ????????for?(int?i?=?0;?i?<?1000;?i++)?{??
  • ????????????exec.submit(ree);??
  • ????????}??
  • ????????System.out.println("number?:?"?+?ree.getNumber());??
  • ????????exec.shutdown();??
  • ????}??
  • }??
  • ?

    ??????????使用AtomicInteger

    Java代碼??
  • import?java.util.concurrent.ExecutorService;??
  • import?java.util.concurrent.Executors;??
  • import?java.util.concurrent.atomic.AtomicInteger;??
  • ??
  • /**?
  • ?*?@author?InJavaWeTrust?
  • ?*/??
  • public?class?TestAtomic?implements?Runnable?{??
  • ??
  • ????private?static?AtomicInteger?number?=?new?AtomicInteger(0);??
  • ??
  • ????public?void?run()?{??
  • ????????increase();??
  • ????}??
  • ??
  • ????public?void?increase()?{??
  • ????????number.getAndAdd(1);??
  • ????}??
  • ??
  • ????public?static?void?main(String[]?args)?{??
  • ????????TestAtomic?ato?=?new?TestAtomic();??
  • ????????ExecutorService?exec?=?Executors.newFixedThreadPool(1000);??
  • ????????for?(int?i?=?0;?i?<?1000;?i++)?{??
  • ????????????exec.submit(ato);??
  • ????????}??
  • ????????System.out.println("number?:?"?+?number.get());??
  • ????????exec.shutdown();??
  • ????}??
  • } ?


  • 來自為知筆記(Wiz)

    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的Java并发_volatile实现可见性但不保证原子性的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。