亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

Java?volatile關鍵字的特性是什么

發布時間:2022-12-13 09:15:29 來源:億速云 閱讀:116 作者:iii 欄目:開發技術

這篇文章主要講解了“Java volatile關鍵字的特性是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java volatile關鍵字的特性是什么”吧!

一、概述

volatile是Java中的關鍵字,用來修飾會被不同線程訪問和修改的變量。

volatile是Java虛擬機提供的輕量級的同步機制,它有三個特性:

(1)保證可見性

(2)不保證原子性

(3)禁止指令重排

二、特性詳解

volatile保證可見性

Java內存模型(JMM)定義了一組規則、規范,規定了程序中各個變量的訪問方法。JMM關于同步的規定:

(1)線程解鎖前,必須把共享變量的值刷新回主內存;

(2)線程加鎖前,必須讀取主內存的最新值同步到自己的工作內存;

(3)加鎖解鎖必須是同一把鎖;

說明:由于JVM運行程序的實體是線程,創建每個線程時,JMM會為其創建一個工作內存(也稱棧空間),工作內存是每個線程的私有數據區域。

Java內存模型規定所有變量都存儲在主內存,主內存是共享內存區域,所有線程都可以訪問。

但是線程對變量的操作(讀取、賦值等)必須在工作內存中進行。因此首先要將變量從主內存拷貝到自己的工作內存,然后對變量進行操作,操作完成后再將變量寫會主內存中。

舉例說明:

(1)火車票賣票系統還剩下一張票,并已經刷入到主內存中:ticketNum = 1;

(2)此時有3個用戶在同時購買票,3個線程都讀入了目前的票數,ticketNum=1,那么線程就會繼續進入購買流程。

(3)假設其中一個線程先搶占了CPU資源,先買到票,并將自己的工作內存中的ticketNum值改為0,ticketNum=0,然后再寫回到主內存。

這時,由于一個線程的用戶已經買到了票,那么其他用戶的線程應該不能再繼續進入購買票的流程了,因此需要系統通知到其他線程 ticketNum=0 這個消息。如果可以達到這樣的效果,可以理解為 具有可見性。

無可見性代碼演示:

@Test
public void test1() {
    DataDemo dataDemo = new DataDemo();
    RunThread runThread = new RunThread(dataDemo);
    runThread.start();
    while (dataDemo.getNumber() == 0) {
    }
    System.out.println("具有可見性驗證通過");
}
public class DataDemo {
    private int number = 0;
    public void add() {
        this.number = this.number + 10;
    }
    public int getNumber() {
        return number;
    }
}
public class RunThread extends Thread {
    private DataDemo dataDemo;
    public RunThread(DataDemo dataDemo) {
        this.dataDemo = dataDemo;
    }
    @Override
    public void run() {
        System.out.println("線程[" + Thread.currentThread().getName() + "] 正在執行");
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        dataDemo.add();
        System.out.println("線程[" + Thread.currentThread().getName() + "]更新后,number值為:" + dataDemo.getNumber());
    }
}

執行結果:
線程[Thread-0] 正在執行
線程[Thread-0]更新后,number值為:10

Java?volatile關鍵字的特性是什么

結果分析:

可以看出子線程啟動后將number值改為了10,雖然已經改為了非0,但是主線程仍然一直處于while循環中,因此此時number不具有可見性,系統不會主動通知主線程number值修改。

原理說明:

這個問題其實就是私有堆棧中的值和公共堆棧中的值不同步造成的。解決這樣的問題就要使用 volatile 關鍵字了,它主要的作用就是當線程訪問number這個變量時,強制性從公共堆棧中進行取值。

Java?volatile關鍵字的特性是什么

可見性代碼演示:

@Test
public void test1() {
    DataDemo dataDemo = new DataDemo();
    RunThread runThread = new RunThread(dataDemo);
    runThread.start();
    while (dataDemo.getNumber() == 0) {
    }
    System.out.println("具有可見性驗證通過");
}
public class DataDemo {
    // 給變量 number 添加 volatile 關鍵字修飾
    volatile private int number = 0;
    public void add() {
        this.number = this.number + 10;
    }
    public int getNumber() {
        return number;
    }
}
public class RunThread extends Thread {
    private DataDemo dataDemo;
    public RunThread(DataDemo dataDemo) {
        this.dataDemo = dataDemo;
    }
    @Override
    public void run() {
        System.out.println("線程[" + Thread.currentThread().getName() + "] 正在執行");
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        dataDemo.add();
        System.out.println("線程[" + Thread.currentThread().getName() + "]更新后,number值為:" + dataDemo.getNumber());
    }
}

執行結果:
線程[Thread-0] 正在執行
線程[Thread-0]更新后,number值為:10
具有可見性驗證通過

結果分析:

通過對變量number變量添加了volatile關鍵字修飾,可以看出子線程啟動后將number值改為了10,隨后主線程跳出了while循環,輸出了“具有可見性驗證通過”,說明此時number具有可見性。

原理說明:

通過使用 volatile 關鍵字,強制從公共內存中讀取變量的值,內存結構如圖:

Java?volatile關鍵字的特性是什么

感謝各位的閱讀,以上就是“Java volatile關鍵字的特性是什么”的內容了,經過本文的學習后,相信大家對Java volatile關鍵字的特性是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

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

AI

铜川市| 毕节市| 宁蒗| 昌乐县| 舒城县| 玉环县| 德清县| 灌云县| 历史| 奉节县| 伊金霍洛旗| 鸡东县| 凤庆县| 崇仁县| 布拖县| 正镶白旗| 治县。| 定日县| 巴彦县| 兰考县| 陕西省| 迭部县| 曲沃县| 张家港市| 汕尾市| 简阳市| 越西县| 永胜县| 麻江县| 弥渡县| 安丘市| 延寿县| 滦平县| 基隆市| 武宣县| 宝丰县| 阿巴嘎旗| 罗甸县| 盐城市| 周至县| 蓬莱市|