" />

最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java 中的volatile關(guān)鍵字

 更新時(shí)間:2021年12月12日 12:03:49   作者:bkpp976  
這篇文章主要介紹了java 中的volatile關(guān)鍵字,volatile在多處理器開(kāi)發(fā)中保證共享變量的“可見(jiàn)性”??梢?jiàn)性的意思是當(dāng)一個(gè)線程修改一個(gè)共享變量時(shí),另一個(gè)一個(gè)線程立馬可以讀到這個(gè)修改的值。下面我們來(lái)看看文章的具體介紹內(nèi)容吧

1.volatile實(shí)現(xiàn)可見(jiàn)性的原理是什么?

volatile變量修飾的共享變量進(jìn)行寫(xiě)操作的時(shí)候匯編代碼會(huì)多出一個(gè)Lock前綴指令。

在該指令下,多核處理器會(huì)引發(fā)兩件事:

  • 將當(dāng)前處理器緩存行的數(shù)據(jù)寫(xiě)回系統(tǒng)內(nèi)存
  • 這個(gè)寫(xiě)回內(nèi)存的操作會(huì)使在其他CPU里緩存了該內(nèi)存地址的數(shù)據(jù)無(wú)效

這里需要簡(jiǎn)單了解CPU緩存一致性問(wèn)題:多核處理器環(huán)境下,每個(gè)CPU都有自己的緩存行,緩存了內(nèi)存中的數(shù)據(jù),要維護(hù)多個(gè)CPU中緩存的數(shù)據(jù)一致性,就需要解決兩個(gè)問(wèn)題:

  • 一是寫(xiě)傳播(某個(gè)CPU里的cache數(shù)據(jù)更新時(shí),需要傳播到其他CPU的cache中);
  • 二是事務(wù)的串行化執(zhí)行(在某個(gè)CPU里對(duì)數(shù)據(jù)的修改,在其他CPU中看起來(lái)順序是一樣的,也就是要引入近似[鎖]的概念,保證同一時(shí)刻只有一個(gè)CPU可以對(duì)數(shù)據(jù)做修改);

寫(xiě)傳播是通過(guò)[總線嗅探]完成的:通過(guò)總線把修改數(shù)據(jù)的事件廣播通知給其他所有的核心,每個(gè)CPU核心都會(huì)監(jiān)聽(tīng)總線上的廣播事件,并檢查是否有相同的數(shù)據(jù)在自己的Cache里面;而事務(wù)的串行化則通過(guò)[MESI協(xié)議]來(lái)完成。

MESI(Modified(已修改)、Exclusive(獨(dú)占)、Shared(共享)、Ivalidated(已失效))協(xié)議中,如果要修改一個(gè)共享數(shù)據(jù),不能直接修改,要先向其他CPU廣播一個(gè)請(qǐng)求,把其他CPU cache中對(duì)應(yīng)的數(shù)據(jù)狀態(tài)改為Invalidated;以后其他CPU在讀取標(biāo)記為Invalidated的數(shù)據(jù)時(shí),需要強(qiáng)制從內(nèi)存中讀取數(shù)據(jù)。

2.演示volatile的可見(jiàn)性

public class VolatileDemo {
    static  int flag = 1;  // 定義一個(gè)共享變量
    public static void main(String[] args) {
        // 兩個(gè)線程,一個(gè)線程負(fù)責(zé)讀取flag的值,另一個(gè)線程負(fù)責(zé)修改flag的值
        new Thread(){
            int localflag = flag;
            @Override
            public void run() {
                while(true){
                    //flag被修改后就跟localflag不一樣了
                    if(localflag!=flag){
                        System.out.println("讀到了flag修改后的值:"+ flag);
                        //把讀到的值賦值給本地變量
                        localflag = flag;
                    }
                }
            }
        }.start();

        new Thread(){
            int localflag = flag;
            @Override
            public void run() {
                while (true){
                    //一直對(duì)flag的值進(jìn)行修改
                    System.out.println("對(duì)flag的值進(jìn)行修改:"+ ++localflag);
                    flag = localflag;
                    //休眠一秒更好地觀察結(jié)果
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();


    }
}

可以看到另一個(gè)線程并不能及時(shí)讀取到被修改的值。

共享變量用volatile修飾后:

public class VolatileDemo {
    static  volatile int flag = 1;
    public static void main(String[] args) {
        // 兩個(gè)線程,一個(gè)線程負(fù)責(zé)讀取flag的值,另一個(gè)線程負(fù)責(zé)修改flag的值
        new Thread(){
            int localflag = flag;
            @Override
            public void run() {
                while(true){
                    //flag被修改后就跟localflag不一樣了
                    if(localflag!=flag){
                        System.out.println("讀到了flag修改后的值:"+ flag);
                        //把讀到的值賦值給本地變量
                        localflag = flag;
                    }
                }
            }
        }.start();

        new Thread(){
            int localflag = flag;
            @Override
            public void run() {
                while (true){
                    //一直對(duì)flag的值進(jìn)行修改
                    System.out.println("對(duì)flag的值進(jìn)行修改:"+ ++localflag);
                    flag = localflag;
                    //休眠一秒更好地觀察結(jié)果
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();


    }
}

可以看到用volatile修飾后,每次另一個(gè)線程總能讀取到修改后的值。

到此這篇關(guān)于java 中的volatile關(guān)鍵字的文章就介紹到這了,更多相關(guān)volatile關(guān)鍵字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 對(duì)dbunit進(jìn)行mybatis DAO層Excel單元測(cè)試(必看篇)

    對(duì)dbunit進(jìn)行mybatis DAO層Excel單元測(cè)試(必看篇)

    下面小編就為大家?guī)?lái)一篇對(duì)dbunit進(jìn)行mybatis DAO層Excel單元測(cè)試(必看篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • mybatis-plus主鍵策略生成失敗的解決

    mybatis-plus主鍵策略生成失敗的解決

    本文主要介紹了mybatis-plus主鍵策略生成失敗的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • JAVA環(huán)境搭建之MyEclipse10+jdk1.8+tomcat8環(huán)境搭建詳解

    JAVA環(huán)境搭建之MyEclipse10+jdk1.8+tomcat8環(huán)境搭建詳解

    本文詳細(xì)講解了MyEclipse10+jdk1.8+tomcat8的JAVA環(huán)境搭建方法,希望能幫助到大家
    2018-10-10
  • Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之二叉堆

    Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之二叉堆

    二叉堆是一種特殊的堆,其實(shí)質(zhì)是完全二叉樹(shù)。二叉堆有兩種:最大堆和最小堆。最大堆是指父節(jié)點(diǎn)鍵值總是大于或等于任何一個(gè)子節(jié)點(diǎn)的鍵值。而最小堆恰恰相反,指的是父節(jié)點(diǎn)鍵值總是小于任何一個(gè)子節(jié)點(diǎn)的鍵值
    2022-02-02
  • Java中的HashMap內(nèi)存泄漏問(wèn)題詳解

    Java中的HashMap內(nèi)存泄漏問(wèn)題詳解

    這篇文章主要介紹了Java中的HashMap內(nèi)存泄漏問(wèn)題詳解,WeakHashMap中的key是弱引用,如果再使用之后沒(méi)有及時(shí)remove掉這個(gè)key,那么當(dāng)GC時(shí)key就可能會(huì)被回收,導(dǎo)致key對(duì)應(yīng)的value對(duì)象占用的內(nèi)存無(wú)法回收進(jìn)而導(dǎo)致內(nèi)存泄漏,需要的朋友可以參考下
    2023-09-09
  • SpringBoot集成jersey打包jar找不到class的處理方法

    SpringBoot集成jersey打包jar找不到class的處理方法

    這篇文章主要介紹了SpringBoot集成jersey打包jar找不到class的處理方法,文中通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-03-03
  • Spring?IOC容器Bean注解創(chuàng)建對(duì)象組件掃描

    Spring?IOC容器Bean注解創(chuàng)建對(duì)象組件掃描

    這篇文章主要為大家介紹了Spring?IOC容器Bean注解創(chuàng)建對(duì)象組件掃描,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 源碼分析SpringMvc日志打印被忽略輸出問(wèn)題

    源碼分析SpringMvc日志打印被忽略輸出問(wèn)題

    這篇文章主要為大家介紹了源碼分析SpringMvc日志打印被忽略輸出問(wèn)題,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Java線程的生命周期和狀態(tài)控制_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java線程的生命周期和狀態(tài)控制_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了Java線程的生命周期和狀態(tài)控制,需要的朋友可以參考下
    2017-05-05
  • JAVA代碼塊你了解嗎

    JAVA代碼塊你了解嗎

    這篇文章主要介紹了舉例說(shuō)明Java中的代碼塊,包括靜態(tài)屬性和非靜態(tài)屬性以及構(gòu)造函數(shù)等相關(guān)的執(zhí)行先后,需要的朋友可以參考下
    2021-09-09

最新評(píng)論

开鲁县| 赤水市| 扶余县| 伊宁县| 鹿邑县| 裕民县| 韩城市| 衡水市| 阿图什市| 余江县| 延津县| 贞丰县| 新竹县| 南皮县| 神木县| 新疆| 漳浦县| 朝阳区| 望都县| 钦州市| 清远市| 驻马店市| 北流市| 汾西县| 紫云| 时尚| 咸阳市| 云龙县| 饶平县| 永春县| 石屏县| 乐清市| 城步| 长宁县| 天祝| 全南县| 达拉特旗| 成都市| 龙泉市| 海原县| 张家界市|