中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

java多線程Synchronized如何實現可見性

發布時間:2021-12-03 09:04:15 來源:億速云 閱讀:414 作者:小新 欄目:開發技術

這篇文章主要為大家展示了“java多線程Synchronized如何實現可見性”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“java多線程Synchronized如何實現可見性”這篇文章吧。

Synchronized實現可見性原理

可見性

要實現共享變量的可見性,必須保證兩點:

  • 線程修改后的共享變量值能夠及時從工作內存刷新到主內存中

  • 其他線程能夠及時把共享變量的最新值從主內存更新到自己的工作內存中

Java語言層面支持的可見性的實現方式

  • synchronized

  • volatile

synchronized實現可見性

synchronized能夠實現:

  • 原子性(同步)

  • 可見性

JMM關于synchronized的兩條規定:

  • 1.線程解鎖前,必須把貢獻變量的最新值刷新到主內存中

  •  2.線程加鎖時,將清空工作內存中共享變量的值,從而使用共享變量時需要從主內存中重新讀取最新的值(注意:加鎖與解鎖需要同一把鎖)

線程解鎖前對共享變量的修改在下次加鎖時對其他線程可見

線程執行互斥代碼的過程

  • 獲取互斥鎖

  • 清空工作內存

  • 從主內存拷貝變量的最新副本到工作內存

  • 執行代碼

  • 將更改后的共享變量的值刷新到主內存

  • 釋放互斥鎖

重排序:

代碼書寫的順序與實際執行的順序不同,指令重排序是編譯器或處理器為了提高程序性能而做得優化

  • 編譯器優化的重排序(編譯器優化)

  • 指令級并行重排序(處理器優化)

  • 內存系統的重排序(處理器優化)

java多線程Synchronized如何實現可見性

as-if-serial

as-if-serial:無論如何重排序,程序執行的結果應該與代碼順序執行的結果一致(Java編譯器、運行時和處理器都會保證Java在單線程下遵循as-if-serial語義)

java多線程Synchronized如何實現可見性

public class SynchronizedTest {
    /**
     * 共享變量
     */
    private boolean ready = false;
    private int result = 0;
    private int number = 1;

    /**
     * 寫操作
     */
    public void write(){
        ready = true;//1.1
        number = 2;//1.2
    }
    /**
     * 讀操作
     */
    public void read(){
        if(ready){//2.1
            result=number*3;//2.2
        }
        System.out.println("result的值為:"+result);
    }
    /**
     * 內部線程類
     */
    private class ReadWriteThread extends Thread{
        //根據構造方法中傳入的flag參數,確定線程執行讀操作還是寫操作
        private boolean flag;
        public ReadWriteThread(boolean flag){
            this.flag=flag;
        }

        @Override
        public void run() {
            if(flag){
                //構造方法中傳入true,執行寫操作
                write();
            }else{
                //構造方法中傳入false,執行讀操作
                read();
            }
        }
    }

    public static void main(String[] args) {
        SynchronizedTest synchronizedTest = new SynchronizedTest();
        //啟動線程執行寫操作
        synchronizedTest.new ReadWriteThread(true).start();
        //啟動線程執行讀操作
        synchronizedTest.new ReadWriteThread(false).start();
    }
}

導致共享變量在線程間不可見的原因

1.線程的交叉執行
eg:上述程序執行步驟為1.1-》2.1-》2.2-》1.2

java多線程Synchronized如何實現可見性

eg:上述程序執行步驟為1.2-》2.1-》2.2-》1.1

java多線程Synchronized如何實現可見性

2.重排序結合線程交叉執行
eg: 2.1和2.2重排序后

int mid = number*3;
if(ready){
	result=mid;
}

共享變量更新后的值沒有在工作內存與主內存間及時更新

安全性代碼

public class SynchronizedTest {
    /**
     * 共享變量
     */
    private boolean ready = false;
    private int result = 0;
    private int number = 1;

    /**
     * 寫操作
     */
    public synchronized void write(){
        ready = true;//1.1
        number = 2;//1.2
    }
    /**
     * 讀操作
     */
    public synchronized void read(){
        if(ready){//2.1
            result=number*3;//2.2
        }
        System.out.println("result的值為:"+result);
    }
    /**
     * 內部線程類
     */
    private class ReadWriteThread extends Thread{
        //根據構造方法中傳入的flag參數,確定線程執行讀操作還是寫操作
        private boolean flag;
        public ReadWriteThread(boolean flag){
            this.flag=flag;
        }

        @Override
        public void run() {
            if(flag){
                //構造方法中傳入true,執行寫操作
                write();
            }else{
                //構造方法中傳入false,執行讀操作
                read();
            }
        }
    }

    public static void main(String[] args) {
        SynchronizedTest synchronizedTest = new SynchronizedTest();
        //啟動線程執行寫操作
        synchronizedTest.new ReadWriteThread(true).start();
        //啟動線程執行讀操作
        synchronizedTest.new ReadWriteThread(false).start();
    }
}

java多線程Synchronized如何實現可見性

以上是“java多線程Synchronized如何實現可見性”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

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

AI

垣曲县| 准格尔旗| 张家川| 昭觉县| 金平| 正安县| 梁河县| 南宁市| 光山县| 吉安县| 科技| 桂平市| 香港| 外汇| 中牟县| 新源县| 永丰县| 衡阳县| 宜兰市| 七台河市| 增城市| 织金县| 山西省| 涡阳县| 信丰县| 获嘉县| 星子县| 邵阳县| 临江市| 马公市| 花莲县| 双桥区| 盐城市| 锡林浩特市| 清河县| 迭部县| 分宜县| 永仁县| 太仓市| 葵青区| 双城市|