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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

synchronized实现可见性对比volatile

發布時間:2023/12/31 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 synchronized实现可见性对比volatile 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近花時間研究了下,如有不正確的地方,歡迎大家批評指正,謝謝。

首先先介紹一下JMM(JAVA內存模型),上圖:

java內存模型的工作原理如上圖所示,一些被定義的變量都存放在主內存中,當一個線程想要修改一個變量的值時,那么這個變量會從主內存中拷貝到線程的工作內存(CPU緩存)中。之后線程對變量值做了更改,又會重新拷貝回主內存中。大家通過描述也可以看出來這些操作是分步執行的,這樣就無法保證可見性和原子性。對于這種情況java也給出了很多解決辦法,今天跟大家分享一下我對synchronized以及volatile的理解。

?

大家知道synchronized是通過加互斥鎖來實現原子性的,JMM關于synchronized的兩條規定:

  • 線程解鎖前,必須把共享變量的最新之刷新到主內存中
  • 線程加鎖前,將清空工作內存中共享變量的值,從而使用共享變量時需要從主內存中重新讀取最新的值(注意:加鎖與解鎖需要時同一把鎖)
  • 我來簡單描敘一下線程執行互斥代碼的過程:

  • 獲得互斥鎖
  • 清空工作內存
  • 從主內存拷貝變量的最新副本到工作內存
  • 執行代碼
  • 將更改后的共享變量的值刷新到主內存
  • 釋放互斥鎖
  • synchronized從而實現類原子性,也具備內存可見性。

    這里多說一下Lock,其實原理跟synchronized類似,但是比synchronized更加靈活,我們會在下一篇博客中詳細探討synchronized的缺陷以及Lock的基本用法。

    volatile是如何實現內存可見性的呢?

    深入來說:是通過加入內存屏障和禁止重排序優化來實現的。(重排序指單線程中在保證執行結果不變的前提下java虛擬機為了提升處理速度可能會將指令重排,達到最合理化)

    • 對volatile變量執行寫操作時,會在寫操作后加入一條store屏障指令
  • 改變線程工作內存中的volatile變量副本的值
  • 將改變后的副本的值從工作內存刷新到主內存
  • ?

    • 對volatile變量執行讀操作時,會在讀操作前加入一條load屏障指令
  • 從主內存中讀取volatile變量的最新值到線程的工作內存中
  • 從工作內存中讀取volatile變量的副本
  • 簡單來說:volatile變量在每次被線程訪問時,都強迫從sy主內存中重讀變量的值,而當該變量發生變化時,又會強迫線程將最新的值刷新到主內存。這樣在任何時刻,不同的線程總能看到該變量的最新值。從而保證了變量的內存可見性。

    ?

    synchronized和volatile的比較

  • volatile不需要加鎖,比synchronized更加輕量級,不會阻塞線程
  • 從內存可見性講,volatile讀相當于加鎖,volatile寫相當于解鎖
  • synchronized既能保證可見性,又能保證原子性,而volatile只能保證可見性,無法保證原子性
  • ?

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的synchronized实现可见性对比volatile的全部內容,希望文章能夠幫你解決所遇到的問題。

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