網站首頁 編程語言 正文
一、JMM的內存可見性保證
按程序類型,Java程序的內存可見性保證可以分為下列3類:
單線程程序:單線程程序不會出現內存可見性問題。編譯器、runtime和處理器會共同確保單線程程序的執行結果與該程序在順序一致性模型中的執行結果相同。
正確同步的多線程程序:正確同步的多線程程序的執行將具有順序一致性(程序的執行結果與該程序在順序一致性內存模型中的執行結果相同)。這是JMM關注的重點,JMM通過限制編譯器和處理器的重排序來為程序員提供內存可見性保證。
未同步/未正確同步的多線程程序:JMM為它們提供了最小安全性保障:線程執行時讀取到的值,要么是之前某個線程寫入的值,要么是默認值未同步程序在JMM中的執行時,整體上是無序的,其執行結果無法預知。 JMM不保證未同步程序的執行結果與該程序在順序一致性模型中的執行結果一致。
二、volatile的內存語義
1、volatile的特性
可見性:對一個volatile變量的讀,總是能看到(任意線程)對這個volatile變量最后的寫入。
原子性:對任意單個volatile變量的讀/寫具有原子性,但類似于volatile++這種復合操作不具有原子性(基于這點,我們通過會認為volatile不具備原子性)。volatile僅僅保證對單個volatile變量的讀/寫具有原子性,而鎖的互斥執行的特性可以確保對整個臨界區代碼的執行具有原子性。
有序性:對volatile修飾的變量的讀寫操作前后加上各種特定的內存屏障來禁止指令重排序來保障有序性。
volatile 寫-讀的內存語義:
當寫一個volatile變量時,JMM會把該線程對應的本地內存中的共享變量值刷新到主內存。
當讀一個volatile變量時,JMM會把該線程對應的本地內存置為無效,線程接下來將從主內存中讀取共享變量。
2、volatile可見性實現原理
JMM內存交互層面實現:volatile修飾的變量的read、load、use操作和assign、store、write必須是連續的,即修改后必須立即同步回主內存,使用時必須從主內存刷新,由此保證volatile變量操作對多線程的可見性。
硬件層面實現:通過lock前綴指令,會鎖定變量緩存行區域并寫回主內存,這個操作稱為“緩存鎖定”,緩存一致性機制會阻止同時修改被兩個以上處理器緩存的內存區域數據。一個處理器的緩存回寫到內存會導致其他處理器的緩存無效。
三、指令重排序
Java語言規范規定JVM線程內部維持順序化語義。即只要程序的最終結果與它順序化情況的結果相等,那么指令的執行順序可以與代碼順序不一致,此過程叫指令的重排序。指令重排序的意義:JVM能根據處理器特性(CPU多級緩存系統、多核處理器等)適當的對機器指令進行重排序,使機器指令能更符合CPU的執行特性,最大限度的發揮機器性能。在編譯器與CPU處理器中都能執行指令重排優化操作。
JMM內存屏障插入策略:
- 在每個volatile寫操作的前面插入一個StoreStore屏障
- 在每個volatile寫操作的后面插入一個StoreLoad屏障
- 在每個volatile讀操作的后面插入一個LoadLoad屏障
- 在每個volatile讀操作的后面插入一個LoadStore屏障
不同硬件實現內存屏障的方式不同,Java內存模型屏蔽了這種底層硬件平臺的差異,由JVM來為不同的平臺生成相應的機器碼。
原文鏈接:https://juejin.cn/post/7127855190010495006
相關推薦
- 2022-01-21 win10 如何做到 C盤 的絕對干凈,所有軟件都安裝到D盤,C盤只用來存操作系統。
- 2022-07-13 rsync下行同步+inotify實時同步部署
- 2022-10-07 C語言函數之memcpy函數用法實例_C 語言
- 2022-11-28 golang進程在docker中OOM后hang住問題解析_Golang
- 2022-10-07 使用Cargo工具高效創建Rust項目_相關技巧
- 2022-11-23 解決vant組件van-list 首屏加載兩次的情況
- 2022-08-04 Go語言學習之WaitGroup用法詳解_Golang
- 2022-03-20 .NET+Sqlite支持加密的操作方法_實用技巧
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支