" />

亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

java 中的volatile關鍵字

 更新時間:2021年12月12日 12:03:49   作者:bkpp976  
這篇文章主要介紹了java 中的volatile關鍵字,volatile在多處理器開發(fā)中保證共享變量的“可見性”??梢娦缘囊馑际钱斠粋€線程修改一個共享變量時,另一個一個線程立馬可以讀到這個修改的值。下面我們來看看文章的具體介紹內容吧

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

volatile變量修飾的共享變量進行寫操作的時候匯編代碼會多出一個Lock前綴指令。

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

  • 將當前處理器緩存行的數(shù)據(jù)寫回系統(tǒng)內存
  • 這個寫回內存的操作會使在其他CPU里緩存了該內存地址的數(shù)據(jù)無效

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

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

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

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

2.演示volatile的可見性

public class VolatileDemo {
    static  int flag = 1;  // 定義一個共享變量
    public static void main(String[] args) {
        // 兩個線程,一個線程負責讀取flag的值,另一個線程負責修改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){
                    //一直對flag的值進行修改
                    System.out.println("對flag的值進行修改:"+ ++localflag);
                    flag = localflag;
                    //休眠一秒更好地觀察結果
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();


    }
}

可以看到另一個線程并不能及時讀取到被修改的值。

共享變量用volatile修飾后:

public class VolatileDemo {
    static  volatile int flag = 1;
    public static void main(String[] args) {
        // 兩個線程,一個線程負責讀取flag的值,另一個線程負責修改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){
                    //一直對flag的值進行修改
                    System.out.println("對flag的值進行修改:"+ ++localflag);
                    flag = localflag;
                    //休眠一秒更好地觀察結果
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();


    }
}

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

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

相關文章

  • MyBatis注解開發(fā)-@Insert和@InsertProvider的使用

    MyBatis注解開發(fā)-@Insert和@InsertProvider的使用

    這篇文章主要介紹了MyBatis注解開發(fā)-@Insert和@InsertProvider的使用,具有很好的參考價值,希望對大家有所幫助。
    2022-07-07
  • 關于@PostConstruct、afterPropertiesSet和init-method的執(zhí)行順序

    關于@PostConstruct、afterPropertiesSet和init-method的執(zhí)行順序

    這篇文章主要介紹了關于@PostConstruct、afterPropertiesSet和init-method的執(zhí)行順序,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 兩個jar包下相同包名類名引入沖突的解決方法

    兩個jar包下相同包名類名引入沖突的解決方法

    本文主要介紹了兩個jar包下相同包名類名引入沖突的解決方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 圖解Java排序算法之堆排序

    圖解Java排序算法之堆排序

    這篇文章主要為大家詳細介紹了Java經典排序算法之堆排序,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 使用java實現(xiàn)猜拳小游戲

    使用java實現(xiàn)猜拳小游戲

    這篇文章主要為大家詳細介紹了使用java實現(xiàn)猜拳小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Java中的接口知識匯總

    Java中的接口知識匯總

    本文給大家匯總介紹了在java中的接口知識,包括為什么要使用接口、什么是接口、抽象類和接口的區(qū)別、如何定義接口以及定義接口注意點,希望大家能夠喜歡
    2016-04-04
  • Java中keytool的使用

    Java中keytool的使用

    Keytool 是一個JAVA環(huán)境下的安全鑰匙與證書的管理工具,Keytool將密鑰(key)和證書(certificates)存在一個稱為keystore 的文件(受密碼保護)中,本文重點給大家介紹keytool的使用,感興趣的朋友一起看看吧
    2022-02-02
  • java框架基礎之SPI機制實現(xiàn)及源碼解析

    java框架基礎之SPI機制實現(xiàn)及源碼解析

    這篇文章主要為大家介紹了java框架基礎之SPI機制實現(xiàn)及源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • 詳解Redis 緩存 + Spring 的集成示例

    詳解Redis 緩存 + Spring 的集成示例

    本篇文章主要介紹了Redis 緩存 + Spring 的集成示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • 詳解如何查看Elasticsearch的Debug日志

    詳解如何查看Elasticsearch的Debug日志

    這篇文章主要為大家介紹了詳解如何查看Elasticsearch的Debug日志,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11

最新評論