色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

volatile的原理

科技綠洲 ? 來源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-10-10 16:33 ? 次閱讀

今天來了解一下面試題:你對(duì) volatile 了解多少。要了解 volatile 關(guān)鍵字,就得從 Java 內(nèi)存模型開始。最后到 volatile 的原理。

一、Java 內(nèi)存模型 (JMM)

大家都知道 Java 程序可以做到一次編寫然后到處運(yùn)行。這個(gè)功勞要?dú)w功于 Java 虛擬機(jī)。Java 虛擬機(jī)中定義了一種 Jva 內(nèi)存模型(JMM),用來屏蔽掉各種硬件和操作系統(tǒng)之間內(nèi)存訪問差異,讓 Java 程序可以在各個(gè)平臺(tái)中訪問變量達(dá)到相同的效果。

JMM 的主要目標(biāo)是定義了程序中變量的訪問規(guī)則,就是內(nèi)存中存放和讀取變量的一些底層的細(xì)節(jié)。

JMM 規(guī)則

  1. 變量包含實(shí)例字段,靜態(tài)字段,構(gòu)成數(shù)組對(duì)象的元素,不包含局部變量和方法參數(shù)。
  2. 變量都存儲(chǔ)在主內(nèi)存上。
  3. 每個(gè)線程在 CPU 中都有自己的 工作內(nèi)存 ,工作內(nèi)存保存了被該線程使用到的變量的主內(nèi)存副本拷貝。
  4. 線程對(duì)變量的所有操作都只能在工作內(nèi)存,不能直接讀寫主內(nèi)存的變量。
  5. 不同線程之間無法之間訪問對(duì)方工作內(nèi)存中的變量。

圖片

定義一個(gè)靜態(tài)變量: static int a = 1;

線程 1 工作內(nèi)存指向主內(nèi)存操作
----a = 1--
a = 1<--a = 1線程 1 拷貝主內(nèi)存變量副本
a = 3--a = 1線程 1 修改工作內(nèi)存變量值
a = 3-->a = 3線程 1 工作內(nèi)存變量存儲(chǔ)到主內(nèi)存變量

上面的一系列內(nèi)存操作,在 JMM 中定義了 8 種操作來完成。

JMM 交互

主內(nèi)存和工作內(nèi)存之間的交互,JMM 定義了 8 種操作來完成,每個(gè)操作都是原子性的。

  1. lock (鎖定): 作用于主內(nèi)存變量,把一個(gè)變量標(biāo)識(shí)為一條內(nèi)存獨(dú)占的狀態(tài)。
  2. unlock (解鎖): 作用于主內(nèi)存變量,把 lock 狀態(tài)的變量釋放出來,釋放出來后才能被其他線程鎖定。
  3. read (讀取): 作用于主內(nèi)存變量,把一個(gè)變量的值從主內(nèi)存?zhèn)鬏數(shù)焦ぷ鲀?nèi)存中。
  4. load (載入): 作用于工作內(nèi)存變量,把 read 操作的變量放入到工作內(nèi)存副本中。
  5. use (使用): 作用于工作內(nèi)存變量,把工作內(nèi)存中的變量的值傳遞給執(zhí)行引擎,每當(dāng)虛擬機(jī)遇到需要這個(gè)變量的值的字節(jié)碼指令時(shí)都執(zhí)行這個(gè)操作。
  6. assgin (賦值): 作用于工作內(nèi)存變量,把從執(zhí)行引擎收到的值賦值給工作內(nèi)存變量,每當(dāng)虛擬機(jī)遇到需要賦值變量的值的字節(jié)碼指令時(shí)都執(zhí)行這個(gè)操作。
  7. store (存儲(chǔ)): 作用于工作內(nèi)存變量,把工作內(nèi)存中的一個(gè)變量值,傳送到主內(nèi)存。
  8. write (寫入): 作用于主內(nèi)存變量,把 store 操作的從工作內(nèi)存取到的變量寫入主內(nèi)存變量中。

圖片

從上圖中可知,JMM 交互在一條線程中是不會(huì)出現(xiàn)任何的問題。但是當(dāng)有兩條線程的時(shí)候,線程 1 已經(jīng)修改了變量的值,但是并未刷新到主內(nèi)存時(shí),如果此時(shí)線程 2 讀取變量得到的值并不是線程 1 修改過的數(shù)據(jù)。

當(dāng)引入線程 2 的時(shí)候 定義一個(gè)靜態(tài)變量: static int a = 1;

操作順序線程 1 工作內(nèi)存線程 2 工作內(nèi)存指向主內(nèi)存操作
--------a = 1--
1a = 1--<--a = 1線程 1 拷貝主內(nèi)存變量副本
2a = 3----a = 1線程 1 修改工作內(nèi)存變量值
3a = 3---->a = 1線程 1 工作內(nèi)存變量存儲(chǔ)到主內(nèi)存變量,主內(nèi)存變量還未更新
4.1a = 3a = 1<--a = 3線程 2 拷貝主內(nèi)存變量副本隨后主內(nèi)存變量更新線程 1 工作內(nèi)存變量
4.2a = 3a = 1<--a = 3線程 1 工作內(nèi)存變量存儲(chǔ)到主內(nèi)存變量隨后線程 2 獲取主內(nèi)存變量副本

下面就可以用 volatile 關(guān)鍵字解決問題。

二、volatile

volatile 可以保證變量對(duì)所有線程可見,一條線程修改的值,其他線程對(duì)新值可以立即得知。還可以禁止指令的重排序。

可見性

修改內(nèi)存變量后立刻同步到主內(nèi)存中,其他的線程立刻得知得益于 Java 的先行發(fā)生原則

先行發(fā)生原則中的 volatile 原則:一個(gè) volatile 變量的寫操作先行于后面發(fā)生的這個(gè)變量的讀操作

定義一個(gè)靜態(tài)變量: static int a = 1;

線程 1 工作內(nèi)存線程 2 工作內(nèi)存指向主內(nèi)存操作
------a = 1--
a = 1--<--a = 1線程 1 拷貝主內(nèi)存變量副本
a = 3----a = 1線程 1 修改工作內(nèi)存變量值
a = 3---->a = 1線程 1 工作內(nèi)存變量存儲(chǔ)到主內(nèi)存變量
a = 3a = 3<--a = 3volatile 原則: 主內(nèi)存變量保存線程A工作內(nèi)存變量操作在線程 2 工作內(nèi)存讀取主內(nèi)存變量操作之前

可見性原理

對(duì) volatile 修飾的變量,在執(zhí)行寫操作的時(shí)候會(huì)多出一條 lock 前綴的指令。JVM 將 lock 前綴指令發(fā)送給 CPU ,CPU 處理寫操作后將最后的值立刻寫回主內(nèi)存,因?yàn)橛?MESI 緩存一致性協(xié)議保證了各個(gè) CPU 的緩存是一致的,所以各個(gè) CPU 緩存都會(huì)對(duì)總線進(jìn)行嗅探,本地緩存中的數(shù)據(jù)是否被別的線程修改了。

如果別的線程修改了共享變量的數(shù)據(jù),那么 CPU 就會(huì)將本地緩存的變量數(shù)據(jù)過期掉,然后這個(gè) CPU 上執(zhí)行的線程在讀取共享變量的時(shí)候,就會(huì)從主內(nèi)存重新加載最新的數(shù)據(jù)。

原子性

volatile 并不保證變量具有原子性。

public class VolatileTest implements Runnable {

    public static volatile int num;

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            num++;
        }

    }

    public static void main(String[] args) {
        for(int i = 0; i < 100; i++) {
            VolatileTest t = new VolatileTest();
            Thread t0 = new Thread(t);
            t0.start();
        }
        System.out.println(num);
        
    }
}

這段代碼的結(jié)果有可能不是 100000,有可能小于 100000。因?yàn)?num++ 并不是原子性的。

有序性

volatile 是通過禁止指令重排序來保證有序性。為了優(yōu)化程序的執(zhí)行效率 JVM 在編譯 Java 代碼的時(shí)候或者 CPU 在執(zhí)行 JVM 字節(jié)碼的時(shí)候,不影響最終結(jié)果的前提下會(huì)對(duì)指令進(jìn)行重新排序。

編譯器會(huì)根據(jù)以下策略將內(nèi)存屏障插入到指令中,禁止重排序:

  1. 在 volatile 寫操作之前插入 StoreStore 屏障。禁止和 StoreStore 屏障之前的普通寫操作不會(huì)進(jìn)行重排序。
  2. 在 volatile 寫操作之后插入 StoreLoad 屏障。禁止和 StoreLoad 屏障之后的 volatile 讀寫重排序。
  3. 在 volatile 讀操作之后插入 LoadLoad 屏障。禁止和 LoadLoad 之后的普通讀和 volatile 讀重排序。
  4. 在 volatile 寫操作之后插入 LoadStore 屏障。禁止和 LoadStore 屏障之后的普通寫操作重排序。
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    3102

    瀏覽量

    74893
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    2983

    瀏覽量

    106543
  • 模型
    +關(guān)注

    關(guān)注

    1

    文章

    3464

    瀏覽量

    49837
  • volatile
    +關(guān)注

    關(guān)注

    0

    文章

    46

    瀏覽量

    13233
收藏 0人收藏

    評(píng)論

    相關(guān)推薦

    什么是volatile

    00. 目錄文章目錄00. 目錄01. volatile概述02. volatile應(yīng)用場(chǎng)景03. volatile應(yīng)用示例04. 嵌入式系統(tǒng)中應(yīng)用05. volatile官方說明
    發(fā)表于 10-28 09:23

    c語言volatile的作用

    volatile,則編譯器會(huì)逐一地進(jìn)行編譯并產(chǎn)生相應(yīng)的機(jī)器代碼(產(chǎn)生四條代碼)。volatile變量有兩個(gè)作用:一個(gè)是告訴編譯器不要進(jìn)行優(yōu)化;另一個(gè)是告訴系統(tǒng)始終從內(nèi)存中取變量的地址,而不是從緩存中取變量的值(加volatile
    發(fā)表于 11-03 09:13 ?2485次閱讀
    c語言<b class='flag-5'>volatile</b>的作用

    Volatile與多線程的認(rèn)識(shí)與理解

    volatile是一個(gè)類型修飾符(type specifier),就像大家更熟悉的const一樣,它是被設(shè)計(jì)用來修飾被不同線程訪問和修改的變量。volatile的作用是作為指令關(guān)鍵字,確保本條指令
    發(fā)表于 12-01 10:31 ?1704次閱讀

    java之用volatile和不用volatile的區(qū)別

    volatile是一個(gè)類型修飾符(type specifier),就像大家更熟悉的const一樣,它是被設(shè)計(jì)用來修飾被不同線程訪問和修改的變量。Java具有簡單性、面向?qū)ο蟆⒎植际健⒔研浴踩浴⑵脚_(tái)獨(dú)立與可移植性、多線程、動(dòng)態(tài)性等特點(diǎn)。
    發(fā)表于 12-01 10:52 ?3574次閱讀

    volatile修飾的變量的認(rèn)識(shí)和理解

     談到volatile,理解原子性和易變性是不同的概念這一點(diǎn)很重要,volatile是輕量級(jí)的鎖,它只具備可見性,但沒有原子特性。如果你將一個(gè)域聲明為volatile,那么只要對(duì)這個(gè)域產(chǎn)生了寫操作
    發(fā)表于 12-01 11:36 ?5855次閱讀
    <b class='flag-5'>volatile</b>修飾的變量的認(rèn)識(shí)和理解

    Java中volatile的作用以及用法

    Java 語言中的 volatile 變量可以被看作是一種 “程度較輕的 synchronized”;與 synchronized 塊相比,volatile 變量所需的編碼較少,并且運(yùn)行時(shí)開銷也較少,但是它所能實(shí)現(xiàn)的功能也僅是 synchronized 的一部分。
    發(fā)表于 12-01 12:14 ?7077次閱讀

    volatile變量定義的意義和該用在哪里

    volatile 影響編譯器編譯的結(jié)果,volatile指出 變量是隨時(shí)可能發(fā)生變化的,與volatile變量有關(guān)的運(yùn)算,不要進(jìn)行編譯優(yōu)化,以免出錯(cuò)
    發(fā)表于 03-07 15:29 ?3847次閱讀
    <b class='flag-5'>volatile</b>變量定義的意義和該用在哪里

    C語言類型修飾符Volatile的使用說明

    C語言是我們經(jīng)常需要用到的語言,C語言中的類型修飾符Volatile大家知道怎么使用嗎? volatile是一個(gè)類型修飾符(type specifier).volatile的作用是作為指令關(guān)鍵字
    的頭像 發(fā)表于 09-19 10:54 ?3683次閱讀

    volatile有哪些使用誤區(qū)

    在建立編譯環(huán)境的時(shí)候用typedef定義了指向volatile 單元的指針,最后終于發(fā)現(xiàn)行不通。
    發(fā)表于 08-06 17:34 ?0次下載
    <b class='flag-5'>volatile</b>有哪些使用誤區(qū)

    如何使用C++語法中的volatile

    volatile volatile int i = 10; volatile 關(guān)鍵字是一種類型修飾符,用它聲明的類型變量表示可以被某些編譯器未知的因素(操作系統(tǒng)、硬件、其它線程等)更改。所以
    的頭像 發(fā)表于 09-09 09:38 ?1613次閱讀

    C++基礎(chǔ)語法之volatile、assert()和sizeof()

    volatile volatile int i = 10; volatile 關(guān)鍵字是一種類型修飾符,用它聲明的類型變量表示可以被某些編譯器未知的因素(操作系統(tǒng)、硬件、其它線程等)更改。所以
    的頭像 發(fā)表于 09-09 09:48 ?1425次閱讀

    【嵌入式】C語言中volatile關(guān)鍵字

    00. 目錄文章目錄00. 目錄01. volatile概述02. volatile應(yīng)用場(chǎng)景03. volatile應(yīng)用示例04. 嵌入式系統(tǒng)中應(yīng)用05. volatile官方說明
    發(fā)表于 10-21 10:21 ?6次下載
    【嵌入式】C語言中<b class='flag-5'>volatile</b>關(guān)鍵字

    C語言中的volatile是什么

    學(xué)C語言時(shí)有一個(gè)奇怪的關(guān)鍵字volatile,這到底有什么用呢?
    的頭像 發(fā)表于 02-17 14:29 ?1379次閱讀
    C語言中的<b class='flag-5'>volatile</b>是什么

    volatile的實(shí)現(xiàn)原理分析

    `volatile`是一個(gè)輕量級(jí)的`synchronized`,一般作用于 **變量** ,在多處理器開發(fā)的過程中保證了內(nèi)存的可見性。相比于`synchronized`關(guān)鍵字,`volatile`關(guān)鍵字的執(zhí)行成本更低,效率更高
    的頭像 發(fā)表于 05-11 17:33 ?782次閱讀
    <b class='flag-5'>volatile</b>的實(shí)現(xiàn)原理分析

    介紹下volatile的底層原理

    線程安全的三大特性,原子性、可見性、有序性,這三大特性與我們之前整理的內(nèi)容息息相關(guān)。本篇重點(diǎn)介紹下volatile的底層原理,幫助我們更好的理解java并發(fā)包。
    的頭像 發(fā)表于 06-09 16:17 ?1131次閱讀
    介紹下<b class='flag-5'>volatile</b>的底層原理
    主站蜘蛛池模板: 国产精品女上位在线观看 | 蜜臀AV久久国产午夜福利软件 | 亚洲欧美一区二区成人片 | 13小箩利洗澡无码视频APP | 98久久无码一区人妻A片蜜 | 伊人久久影院大香线蕉 | 欧美亚洲日韩国码在线观看 | 一二三四中文字幕在线看 | 久久国语露脸精品国产 | 亚洲国产精品天堂在线播放 | 成人在线观看视频免费 | 久久99re6热在线播放 | 伊人久久大香网 | 99精品小视频 | 羞羞答答的免费视频在线观看 | 国产亚洲人成网站在线观看播放 | 亚洲精品久久久久69影院 | 日本免费无码A专区在线观看 | 中文字幕绝色少妇性 | 啊灬啊别停灬用力啊在线观看视频 | 99久久精品毛片免费播放 | 欧美老少欢杂交另类 | 麻豆无人区乱码 | 日本动漫henta videos | 在线免费福利 | 亚洲熟妇AV乱码在线观看 | 91久久精品一区二区三区 | 男人边吃奶边摸边做刺激情话 | 国产精品久久久久久免费字体 | 最近免费中文MV在线字幕 | 亚洲第一区欧美日韩精品 | 色婷婷激情AV精品影院 | 久久热国产在线视频 | 欧美高清另类video | 国产精品人妻一区免费看8C0M | 在线欧美 精品 第1页 | 国语大学生自产拍在线观看 | 脱女学小内内摸出水网站免费 | 看看妇女的B免费看 | 天津相声广播在线收听 | 双腿被绑成M型调教PLAY照片 |

    電子發(fā)燒友

    中國電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會(huì)員交流學(xué)習(xí)
    • 獲取您個(gè)性化的科技前沿技術(shù)信息
    • 參加活動(dòng)獲取豐厚的禮品