volatile關鍵字的特性及證明

来源:https://www.cnblogs.com/dream2true/archive/2019/04/22/10753625.html
-Advertisement-
Play Games

volatile是java虛擬機提供的輕量級的同步機制 JMM(Java記憶體模型)是圍繞著併發編程中原子性、可見性、有序性這三個特征來建立的 原子性:一個操作或多個操作要麼全部執行完成且執行過程不被中斷,要麼就不執行。 可見性:當多個線程同時訪問同一個變數時,一個線程修改了這個變數的值,其他線程能夠 ...


volatile是java虛擬機提供的輕量級的同步機制

JMM(Java記憶體模型)是圍繞著併發編程中原子性、可見性、有序性這三個特征來建立的

原子性:一個操作或多個操作要麼全部執行完成且執行過程不被中斷,要麼就不執行。

可見性:當多個線程同時訪問同一個變數時,一個線程修改了這個變數的值,其他線程能夠立即看得到修改的值。

有序性:程式執行的順序按照代碼的先後順序執行。

 

volatile保證了可見性,有序性,不保證原子性

 

證明可見性的代碼:

 1 package concurrent;
 2 
 3 import java.util.concurrent.TimeUnit;
 4 
 5 /*
 6  * @description: volatile特性
 7  * @date 2019.04.22 20:48
 8  */
 9 //數據類
10 class Mydata{
11 
12     volatile int num = 0;
13 
14     public void changeNum(){
15         this.num = 100;
16     }
17 }
18 
19 public class VolatileDemo {
20 
21     public static void main(String[] args)  throws InterruptedException{
22         Mydata mydata = new Mydata();
23         new Thread(() -> {
24             System.out.println("===="+Thread.currentThread().getName() +"線程啟動===");
25             //暫停3秒
26             try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {}
27             //3秒後t1線程改變num的值
28             mydata.changeNum();
29             System.out.println(Thread.currentThread().getName()+"線程將num的值改為"+mydata.num);
30         },"t1").start();
31 
32         //num的值不變就一直迴圈
33         long begin = System.currentTimeMillis();
34         while (mydata.num == 0){
35             //num如果不被volatile修飾會一直迴圈
36         }
37         long cost = System.currentTimeMillis() - begin;
38         System.out.printf(Thread.currentThread().getName()+"線程檢測到num的值已經改變,cost{%d},證明瞭volatile的可見性",cost);
39     }
40 }

運行結果為:

====t1線程啟動===
t1線程將num的值改為100
main線程檢測到num的值已經改變,cost{3001},證明瞭volatile的可見性

  

證明不保證原子性的代碼:

class Mydata{

    volatile int num = 0;

    public void changeNum(){
        this.num = 100;
    }

    public void numIncreOne(){
        this.num++;
    }
}

public class VolatileDemo {
    
    public static void main(String[] args)  throws InterruptedException{

        Mydata mydata = new Mydata();
        //開啟10個線程每個線程調用1000次num++
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    mydata.numIncreOne();
                }
            },String.valueOf(i)).start();
        }

        //輸出num的值,如果volatile能保證原子性num將等於10000
        System.out.println(mydata.num);
        System.out.println(mydata.num ==10000?"volatile可以保證原子性":"volatile無法保證原子性");
    }
}

輸出結果:

5856
volatile無法保證原子性

 

多線程環境中,線程交替執行,編譯器會通過對指定進行重排序來進行優化。被volatile修飾的變數不會參與重排序,保證有序性。

證明有序性的代碼:

 1     int num = 0;
 2 
 3     private boolean flag = false;
 4     
 5     private void reSort1(){
 6         num = 1;    //語句1
 7         flag = true; //語句2
 8     }
 9 
10     private void reSort2(){
11         if(flag){
12             num++;
13             System.out.println("num的值為"+num);
14         }
15     }
多線程情況下有可能先執行語句2,再執行語句1,從而導致num只自增1次,輸出為1。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • NumPy: 1、NumPy 是一個功能強大的第三方庫(需要自己安裝),主要用於對多維數組執行計算; 它提供了大量的庫函數和操作,可以幫助程式員更輕鬆地進行數值計算 2、可以和另外兩個第三方庫 SciPy 和 Matplotlib 一起使用從而在一定程度上替換對 Matlab 的使用 3、主要應用: ...
  • R語言基礎學習——D02 20190423內容綱要: 1、前言 2、向量操作 (1)常規操作 (2)不定長向量計算 (3)序列 (4)向量的刪除與保留 3、列表詳解 (1)列表的索引 (2)列表得元素屬性 (3)更改列表元素 (4)刪除列表元素 (5)合併兩個列表 (6)將列表轉換為向量 4、推薦 ...
  • 一、引言 大部分系統都離不開數據訪問,資料庫包括SQL和NOSQL,SQL是指關係型資料庫,常見的有SQL Server,Oracle,MySQL(開源),NOSQL是泛指非關係型資料庫,常見的有MongoDB,Redis。 用spring開發時我們常用的ORM框架有JDBC、Mybatis,Hib ...
  • java.util.logging.Logger——java 中提供的日誌類 實際開發 90% 都是使用 log4j 記錄日誌,而 Log4j 底層就是 java.util.logging.Logger 實現的 Log4j 是一個日誌輸出框架,就是用於輸出日誌的。Mybatis 的日誌輸出是通過 L ...
  • 1.cd 到指定目錄 2.運行命令 python 3之前 python 3+ 3.運行後: 4.在瀏覽器輸入 http://localhost:8888/. 測試,然後就可以瀏覽網頁 ...
  • 閱讀目錄 一、模塊和包 模塊(module)的概念: 在電腦程式的開發過程中,隨著程式代碼越寫越多,在一個文件里代碼會越來越長,越來越不容易維護。 為了編寫可維護的代碼,我們把很多函數分組,分別放到不同的文件里,這樣,每個文件包含的代碼就相對較少,很多編程語言都採用這種組織代碼的方式。在Pytho ...
  • 新聞 "Ionide試驗版本" "FSharp路線圖介紹" "Blazor官方預覽" ".NET Framework 4.8發佈" ".NET Core 3 Preview 4發佈" "需要來自FSharp.Data.SqlClient用戶的反饋" "Fable.React 5發佈" "Though ...
  • 一、介面思想 建立關聯的橋梁,方便管理代碼 介面思想提現:為類拓展功能 介面類:用來定義功能的類,為繼承它的子類提供功能的。 該類的功能方法一般不需要有實現體,實現體有繼承它的子類自己去實現。 介面類:用來定義功能的類,為繼承它的子類提供功能的。 該類的功能方法一般不需要有實現體,實現體有繼承它的子 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...