附1 Java記憶體模型與共用變數可見性

来源:http://www.cnblogs.com/java-zhao/archive/2016/01/12/5124725.html
-Advertisement-
Play Games

註:本文主要參考自《深入理解Java虛擬機(第二版)》和《深入理解Java記憶體模型》1、Java記憶體模型(JMM)Java記憶體模型的主要目標:定義在虛擬機中將變數存儲到記憶體和從記憶體中取出變數這樣的底層細節。註意:上邊的變數指的是共用變數(實例欄位、靜態欄位、數組對象元素),不包括線程私有變數(局部變...


註:本文主要參考自《深入理解Java虛擬機(第二版)》和《深入理解Java記憶體模型》

1、Java記憶體模型(JMM)

Java記憶體模型的主要目標:定義在虛擬機中將變數存儲到記憶體和從記憶體中取出變數這樣的底層細節。

註意:上邊的變數指的是共用變數(實例欄位、靜態欄位、數組對象元素),不包括線程私有變數(局部變數、方法參數),因為私有變數不會存在競爭關係。

1.1、記憶體模型就是一張圖:

說明:

  • 所有共用變數存於主記憶體
  • 每一條線程都有自己的工作記憶體(就是上圖所說的本地記憶體)
  • 工作記憶體中保存了被該線程使用到的變數的主記憶體副本

註意:

  • 線程對變數的操作都要在工作記憶體中進行,不能直接操作主記憶體
  • 不同的線程之間無法直接訪問對方的工作記憶體中的變數
  • 不同線程之間的變數的傳遞必須通過主記憶體

類比:(註意:主記憶體與工作記憶體只是一個概念,與堆棧記憶體沒有關係,下邊的類比只是幫助理解)

  • 主記憶體:對應於Java堆中的對象實例數據部分(註意:堆中還保存了對象的其他信息,eg.Mark Word、Klass Point和用於位元組對其補白的填充數據)
  • 工作記憶體:對應於棧中的部分區域

1.2、8條記憶體屏障指令:

下麵只列出6條與之後內容相關的,其餘的查看《深入理解Java虛擬機》

  • lock:作用於主記憶體,把一個變數標識為一條線程獨占的狀態
  • unlock:作用於主記憶體,把一個處於鎖定的變數解鎖

下邊四條是與volatile實現記憶體可見性直接相關的四條(store、write、read、load)

  • store:把工作記憶體中的變數的值傳送到主記憶體中
  • write:把store操作從工作記憶體中得到的變數值放入到主記憶體的變數中
  • read:把一個變數的值從主記憶體中傳輸到線程的工作記憶體
  • load:把read操作從主記憶體中獲取到的變數值放入工作記憶體的變數中去

註意:

  • 一個變數在同一時刻只允許一條線程對其進行lock操作
  • lock操作會將該變數在所有線程工作記憶體中的變數副本清空,否則就起不到鎖的作用了
  • lock操作可被同一條線程多次進行,lock幾次,就要unlock幾次(可重入鎖)
  • unlock之前必須先執行store-write
  • store-write必須成對出現(工作記憶體-->主記憶體)
  • read-load必須成對出現(主記憶體-->工作記憶體)

 

2、變數對所有線程的可見性

可見性:線程1對共用變數的修改能及時被線程2看到

2.1、共用變數不可見的原因

  • 共用變數更新後的值沒有在工作記憶體和主記憶體之間及時更新
  • 線程交錯執行
  • 指令重排序結合線程交錯執行

2.2、實現共用變數及時更新的措施

線程1修改過共用變數後,將共用變數刷到主記憶體,然後,線程2從主記憶體讀取該共用變數,將該共用變數載入到工作記憶體中

註意:在短時間內的高併發情況下,如果發生下列三種情況,則線程2就讀不到線程1修改過的最新的值了,

  • 可能線程1根本來不及將修改過後的共用變數刷到主記憶體(這個時間非常短,但是還是有)的時候,線程2就已經讀取了原有的主記憶體變數到其工作記憶體中。
  • 可能線程1雖然將修改過後的值刷到了主記憶體中,但是線程2的工作記憶體中的變數副本還沒來得及從CPU刷新回來,所以線程2讀取到的還是原來的工作記憶體中的變數副本
  • 可能線程1根本來不及將修改過後的共用變數刷到主記憶體的時候,同時,線程2的工作記憶體中的變數副本還沒來得及從CPU刷新回來

註意:工作記憶體中的變數副本在使用之後,不會立刻消失掉,會一直存在,這樣其值也一直不變,直到對其進行寫操作或數據從CPU中刷新回來(類比volatile-read的作用)。

2.3、指令重排序:代碼書寫順序與實際執行順序不同(編譯器或處理器為提高程式性能做的優化)

eg.

書寫代碼的順序如下:

1         int a = 12;
2         int b = 13;
3         int c = a+b;
View Code

可能實際執行代碼的順序如下:

1         int b = 13;
2         int a = 12;
3         int c = a+b;
View Code

總結:本文大概介紹了一下Java記憶體模型以及與共用變數可見性的一些概念,為下邊的volatile做準備。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 效果:http://hovertree.com/texiao/html5/canvas/1/代碼: 1 2 3 4 15 測試fillStyle - 何問起16 17 18 19 20 21 22 何問起23 24 更多:http://www.cnblogs.com/roucheng/p...
  • 在一個頁面放2個懸浮框,懸浮框隨頁面的上下滾動有上下波動的效果,最終固定在同一位置體驗效果:http://hovertree.com/texiao/jsstudy/1/代碼如下:JavScript頁面懸浮框- 何問起何問起 特效原文效果在一個頁面放2個懸浮框,懸浮框隨頁面的上下滾動有上下波動的效果,...
  • 效果體驗:http://hovertree.com/texiao/jsstudy/2/實現思路 1 滑鼠移入標題(這裡是標簽) 創建一個div,div的內容為滑鼠位置的文本 將創建好的div加到文檔中 為提示層設置位置 2 滑鼠移出標題 移除div 3 當滑鼠在標題內移...
  • jQuery升級踩坑大全背景jQuery想必各個web工程師都再熟悉不過了,不過現如今很多網站還採用了很古老的jQuery版本。其實如果早期版本使用不當,可能會有DOMXSS漏洞,非常建議升級到jQuery 1.9.x或以上版本。前段時間我就主導了這件事情,把公司里我們組負責的項目jQuery版本從...
  • 利用矩陣乘法來實現剛體的平面運動,並繪製剛體運動前後的圖形用平面坐標系中的一個閉合圖形來描述剛體,用一個矩陣X來描述它。X的一列表示剛體一個頂點的坐標。為了使圖形閉合,X的最後一列和第一列相同;為了實現剛體的平移運算,給矩陣X添加元素值為1的一行,使矩陣X的形狀為3Xn若有矩陣:可以證明:矩陣Y1是...
  • 在使用SimpleMappingExceptionResolver實現統一異常處理後(參考Spring MVC的異常統一處理方法), 發現出現異常時,log4j無法在控制台輸出錯誤日誌。因此需要自定義一個繼承至SimpleMappingExceptionResolver的 RrtongMappin....
  • Laravel框架的依賴註入確實很強大,並且通過容器實現依賴註入可以有選擇性的載入需要的服務,提高初始化框架的開銷,下麵是我在網上看到的一個帖子,寫的很好拿來與大家分享,文章從開始按照傳統的類設計資料庫連接一直到通過容器載入服務這個高度解耦的設計展示了依賴註入的強大之處,值得我們借鑒和學習。--.....
  • 1基礎理論部分 led數位管是由多個發光二極體封裝在一起組合的“8”字型的器件,引線內部已經完成,如下圖10.1所示,圖10.2為實物圖。圖10.1 數位管內部結構 那麼我們想要控制數位管的亮滅,其實也就是控制發光二極體的亮滅,分別用高低電平去控制。對於數位管來說,讀者若是學過單片機及其他MCU的話...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...