老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業提供網站建設、域名注冊、服務器等服務

什么是volatile機制

本篇內容介紹了“什么是volatile機制”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

為懷來等地區用戶提供了全套網頁設計制作服務,及懷來網站建設行業解決方案。主營業務為成都做網站、網站建設、懷來網站設計,以傳統方式定制建設網站,并提供域名空間備案等一條龍服務,秉承以專業、用心的態度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

前提概要

我們都知道synchronized關鍵字的特性:原子性、可見性、有序性、可重入性,雖然,JDK在不斷的嘗試優化這個內置鎖,一文中有提到:無鎖 -> 偏向鎖 -> 輕量鎖 -> 重量鎖一共四種狀態,但是,在高并發的情況下且大量沖突出現的時候,最終都還是會膨脹到重量鎖

為何這么說?

那是因為,synchronized是同步代碼塊通過monitor監視器,對整個代碼塊(方法是通過判斷 ACC_SYNCHRONZED標志位對整個方法)進行了整體原子性操作。而 volatile 對單一操作是原子性的,非單一操作則是非原子性的

基本用法

Java語言里的volatile關鍵字是用來修飾變量的,方式如下入所示。表示:該變量需要直接存儲到主內存中

public class SharedClass {
    public volatile int counter = 0;
}

被volatile關鍵字修飾的 int counter 變量會直接存儲到主內存中并且所有關于該變量的讀操作,都會直接從主內存中讀取,而不是直接從CPU緩存。(關于主內存和CPU緩存的區別,如果不理解也不用擔心,下面會詳細介紹

這么做解決什么問題呢?主要是兩個問題:

  • 多線程見可見性的問題

  • CPU指令重排序的問題

注:為了描述方便,我們接下來會把 volatile 修飾的變量簡稱為“volatile 變量”,把沒有用 volatile 修飾的變量建成為“non-volatile”變量。

理解 volatile 關鍵字

變量可見性問題(Variable Visibility Problem): volatile可以保證變量變化在多線程間的可見性

一個多線程應用中,出于計算性能的考慮,每個線程默認是從主內存將該變量拷貝到線程所在CPU的緩存中,然后進行讀寫操作的。現在電腦基本都是多核CPU,不同的線程可能運行的不同的核上,而每個核都會有自己的緩存空間。如下圖所示(圖中的 CPU 1,CPU 2 大家可以直接理解成兩個核)

什么是volatile機制

這里存在一個問題,JVM既不會保證什么時候把 CPU 緩存里的數據寫到主內存,也不會保證什么時候從主內存讀數據到 CPU 緩存。也就是說,不同 CPU 上的線程,對同一個變量可能讀取到的值是不一致的,這也就是我們通常說的:線程間的不可見問題

比如下圖,Thread 1 修改的 counter = 7 只在 CPU 1 的緩存內可見,Thread 2 在自己所在的 CPU 2 緩存上讀取 counter 變量時,得到的變量 counter 的值依然是 0。

什么是volatile機制

而volatile出現的用意之一,就是要解決線程間不可見性,通過 volatile 修飾的變量,都會變得線程間可見

其解決方式就是文章開頭提到的:

  • 通過 volatile 修飾的變量,所有關于該變量的讀操作,都會直接從主內存中讀取,而不是 CPU 自己的緩存。而所有該變量的寫操都會寫到主內存上。

  • 因為主內存是所有 CPU 共享的,理所當然即使是不同 CPU 上的線程也能看到其他線程對該變量的修改了。volatile不僅僅只保證 volatile變量的可見性,volatile 在可見性上所做的工作,實際上比保證 volatile 變量的可見性更多

當 Thread A 修改了某個被 volatile 變量 V,另一個 Thread B 立馬去讀該變量 V。一旦 Thread B 讀取了變量 V 后,不僅僅是變量 V 對 Thread B 可見, 所有在 Thread A 修改變量 V 之前 Thread A 可見的變量,都將對 Thread B 可見。

當 Thread A 讀取一個 volatile 變量 V 時,所有對于 Thread A 可見的其他變量也都會從主內存中被讀取。

特性及原理

可見性

任意一個線程修改了 volatile 修飾的變量,其他線程可以馬上識別到最新值。實現可見性的原理如下。

  • 步驟 1:修改本地內存,強制刷回主內存。

什么是volatile機制

  • 步驟 2:強制讓其他線程的工作內存失效過期。(此部分更多的屬于MESI協議)

什么是volatile機制

單個讀/寫具有原子性

單個volatile變量的讀/寫(比如 vl=l)具有原子性,復合操作(比如 i++)不具有原子性,Demo 代碼如下:

public class VolatileFeaturesA {
   
   private volatile long vol = 0L;

    /**
     * 單個讀具有原子性
     * @date:2020 年 7 月 14 日 下午 5:02:38
     */
    public long get() {
        return vol;
    }

    /**
     * 單個寫具有原子性
     * @date:2020 年 7 月 14 日 下午 5:01:49
     */
    public void set(long l) {
        vol = l;
    }

    /**
     * 復合(多個)讀和寫不具有原子性
     * @date:2020 年 7 月 14 日 下午 5:02:24
     */
    public void getAndAdd() {
        vol++;
    }

}

互斥性

同一時刻只允許一個線程操作 volatile 變量,volatile 修飾的變量在不加鎖的場景下也能實現有鎖的效果,類似于互斥鎖。上面的 VolatileFeaturesA.java 和下面的 VolatileFeaturesB.java 兩個類實現的功能是一樣的(除了 getAndAdd 方法)。

public class VolatileFeaturesB {
    
	private volatile  long vol = 0L;

    /**
     * 普通寫操作
     * @date:2020 年 7 月 14 日 下午 8:18:34
     * @param l
     */
    public synchronized void set(long l) {  
        vol = l;
    }

    /**
     * 加 1 操作
     * @author songjinzhou
     * @date:2020 年 7 月 14 日 下午 8:28:25
     */
    public void getAndAdd() {
        long temp = get();
        temp += 1L;
        set(temp);
    }

    /**
     * 普通讀操作
     * @date:2020 年 7 月 14 日 下午 8:33:00
     * @return
     */
    public synchronized long get() {
        return vol;
    }
}

部分有序性

JVM 是使用內存屏障來禁止指令重排,從而達到部分有序性效果,看看下面的 Demo 代碼分析自然明白為什么只是部分有序

//a、b 是普通變量,flag 是 volatile 變量
int a = 1;            //代碼 1
int b = 2;            //代碼 2
volatile boolean flag = true;  //代碼 3
int a = 3;            //代碼 4
int b = 4;            //代碼 5

因為 flag 變量是使用 volatile 修飾,則在進行指令重排序時,不會把代碼 3 放到代碼 1 和代碼 2 前面,也不會把代碼 3 放到代碼 4 或者代碼 5 后面。但是指令重排時代碼 1 和代碼 2 順序、代碼 4 和代碼 5 的順序不在禁止重排范圍內,比如:代碼 2 可能會被移到代碼 1 之前。

內存屏障類型分為四類。
    1. LoadLoadBarriers

指令示例:LoadA —> Loadload —> LoadB

此屏障可以保證 LoadB 和后續讀指令都可以讀到 LoadA 指令加載的數據,即讀操作 LoadA 肯定比 LoadB 先執行

    1. StoreStoreBarriers

指令示例:StoreA —> StoreStore —> StoreB

此屏障可以保證 StoreB 和后續寫指令可以操作 StoreA 指令執行后的數據,即寫操作 StoreA 肯定比 StoreB 先執行

    1. LoadStoreBarriers

指令示例: LoadA —> LoadStore —> StoreB

此屏障可以保證 StoreB 和后續寫指令可以讀到 LoadA 指令加載的數據,即讀操作 LoadA 肯定比寫操作 StoreB 先執行

    1. StoreLoadBarriers

指令示例:StoreA —> StoreLoad —> LoadB

此屏障可以保證 LoadB 和后續讀指令都可以讀到 StoreA 指令執行后的數據,即寫操作 StoreA 肯定比讀操作 LoadB 先執行。

實現有序性的原理:

如果屬性使用了 volatile 修飾,在編譯的時候會在該屬性的前或后插入上面介紹的 4 類內存屏障來禁止指令重排,比如

  • volatile寫操作的前面插入 StoreStoreBarriers保證volatile寫操作之前的普通讀寫操作執行完畢后再執行 volatile寫操作。

  • volatile寫操作的后面插入 StoreLoadBarriers保證 volatile寫操作后的數據刷新到主內存,保證之后的 volatile 讀寫操作能使用最新數據(主內存)。

  • volatile讀操作的后面插入 LoadLoadBarriersLoadStoreBarriers保證 volatile 讀寫操作之后的普通讀寫操作先把線程本地的變量置為無效,再把主內存的共享變量更新到本地內存,之后都使用本地內存變量

volatile 讀操作內存屏障:

什么是volatile機制

volatile 寫操作內存屏障:

什么是volatile機制

狀態標志,比如布爾類型狀態標志,作為完成某個重要事件的標識,此標識不能依賴其他任何變量,Demo 代碼如下:

public class Flag {
    //任務是否完成標志,true:已完成,false:未完成
    volatile boolean finishFlag;

    public void finish() {
        finishFlag = true;
    }

    public void doTask() { 
        while (!finishFlag) { 
            //keep do task
        }
    }

一次性安全發布,比如:著名的 double-checked-locking,demo 代碼上面已貼出。 開銷較低的讀,比如:計算器,Demo 代碼如下。

/**
 * 計數器
 */
public class Counter {
    private volatile int value;
    //讀操作無需加鎖,減少同步開銷提交性能,使用 volatile 修飾保證讀操作的可見性,每次都可以讀到最新值 
    public int getValue() {
        return value; 
    }
    //寫操作使用 synchronized 加鎖,保證原子性
    public synchronized int increment() {
        return value++;
    }
}

“什么是volatile機制”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注創新互聯網站,小編將為大家輸出更多高質量的實用文章!


網站題目:什么是volatile機制
網頁鏈接:http://www.xueling.net.cn/article/johsjd.html

其他資訊

在線咨詢
服務熱線
服務熱線:028-86922220
TOP
主站蜘蛛池模板: 亚洲A无码综合A国产AV中文 | 国产精品女同一区二区三区久久夜 | 麻豆国产VA免费精品高清在线 | 高清视频一区二区 | 成全高清视频免费观看动漫版 | 一本大道av| 综合天堂av久久久久久久 | 西西人体大胆无码视频 | 亚洲综合在线视频 | 日本女人一区二区 | 99久久夜色精品国产亚洲1000部 | 女人被爽到高潮视频 | 国产激情久久久久影院老熟女免费 | 久视频精品线在线观看的录制功能 | 国内色视频 | 欧美狠狠操 | 日韩精品在线观看免费 | 浪漫樱花动漫在线观看官网 | 亚洲在女同久久中文字幕 | 亚洲最大一级无码av网站 | 免费观看又黄又爽的视频 | aaaa日韩| 国产成人AV片免费 | 国产精品国产三级国产a | 人人叉人人 | 在线观看区 | 四虎永久影院 | 日韩久久中文字幕 | 九九在线观看免费视频 | 精品乱码一区二区三四区视频 | 九九视频这里只有精品 | 久久中文综合 | 国产日本三级 | 久久妇女高潮几次MBA | 超碰人人艹 | 黄色精品一区二区 | 国产成人免费网站在线观看 | 女人把腿张开让男人来桶 | 97视频在线视频 | 日韩精品网址 | videosgratis侏儒孕交 |