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

溫馨提示×

溫馨提示×

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

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

如何理解Java內存模型

發布時間:2021-10-22 14:41:38 來源:億速云 閱讀:152 作者:iii 欄目:編程語言

本篇內容主要講解“如何理解Java內存模型”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何理解Java內存模型”吧!

(一)概述

很多人會把Java內存區域(運行時數據區)和Java內存模型(JMM)搞混,這兩者是完全不一樣的東西。

Java內存區域是指JVM運行時數據分區域存儲,而Java內存模型是定義了線程和主內存之間的抽象關系,了解Java內存模型是學好Java并發編程的基礎。

(二)Java內存模型

Java內存模型中規定了所有的變量都存儲在主內存中,每條線程還有自己的工作內存,線程對變量的所有操作都必須在工作內存中進行,而不能直接讀寫主內存中的變量。我們來看一張圖:

如何理解Java內存模型

每個線程擁有一個自己的私有工作內存,需要變量時從主內存中拷貝一份到工作內存,如果更新過變量之后再將共享變量刷新到主內存。

但是兩個線程之間,是沒有辦法讀取對方工作內存中的變量值的。看一個例子:

public class Test {
    private static boolean flag=false;
    public static void main(String[] args) throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("waiting");
                while (!flag){}
                System.out.println("in");
            }
        }).start();

        Thread.sleep(2000);
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("change flag");
                flag=true;
                System.out.println("change success");
            }
        }).start();
    }
}

首先定義了一個靜態變量flag為false,A線程等待flag等于true后輸出in,于是我們新開一個線程將flag修改為true。結果是A線程依舊無法輸出in。

如何理解Java內存模型

原理看Java內存模型的圖就理解了,不同的線程修改變量,對本地線程是不可見的。

(三)JMM數據的原子操作

通過上面這段代碼,我們已經知道了Java內存模型的結構,那么工作內存和主內存之間是如何讀取變量又是如何修改變量的呢?JMM提供了對變量的一系列原子操作。我們先不講理論,看個圖,這個圖描述了上面一段代碼的執行過程:

如何理解Java內存模型

整個過程一共十步,重復幾個步驟不講了,我把不重復的六個操作列一下:

read:從主內存讀取數據

load:將主內存讀取到的數據寫入工作內存

use :從工作內存中讀取數據來使用

assign:把計算好的值重新賦值到工作內存中

store:將工作內存數據寫入主內存

write:將store過去的變量賦值給主內存中的變量

通過上面的圖,對下面六個原子操作的理解應該可以更加深刻了。JMM的原子操作一共有八個,下面列出剩下的兩個

lock:將主內存變量加鎖,標識為線程獨占狀態

unlock:將主內存變量解鎖,解鎖后其他線程可以鎖定該變量

(四)JMM緩存不一致問題

從前面的例子我們已經看到了,一個線程修改完數據,另外一個線程無法立即可見,這就是JMM緩存不一致的問題,有兩種解決辦法:

加鎖:

還記得我們沒有用到過的JMM原操作的最后兩個嗎,lock和unlock,使用這兩個操作就可以實現緩存一致性,一個線程想要獲取某個主內存變量時,先使用lock將主內存變量加鎖,只有他才能使用,等用完后再unlock,其他線程才能競爭。但是加鎖意味著性能低。

MESI緩存一致性協議:

這個協議涉及到cpu的總線嗅探機制,從上面的JMM執行的流程圖中我們可以看到當某個線程修改了共享變量后,他會回寫到主內存,MESI緩存一致性協議就是通過cpu的總線嗅探機制,將其他也正在使用該變量的線程的數據失效掉,使得這些線程要重新讀取主內存中的值,從而保證緩存最終一致性。

到此,相信大家對“如何理解Java內存模型”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

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

AI

青铜峡市| 新民市| 扶余县| 碌曲县| 天全县| 肃宁县| 东丰县| 新化县| 珠海市| 思茅市| 台江县| 共和县| 安顺市| 永兴县| 绥中县| 榆中县| 张家界市| 徐州市| 读书| 江西省| 察隅县| 浠水县| 嘉义县| 周口市| 咸阳市| 张家口市| 寿光市| 杂多县| 隆化县| 内黄县| 巫山县| 尖扎县| 武强县| 屏东市| 湾仔区| 高台县| 剑河县| 东安县| 开鲁县| 环江| 宁强县|