成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深入理解Java的Volatile關鍵字

開發(fā) 后端
在Java并發(fā)編程中,volatile關鍵字有著至關重要的作用,在面試中也常常會是必備的一個問題。本文將會介紹volatile關鍵字的作用以及其實現(xiàn)原理。

 前言

在Java并發(fā)編程中,volatile關鍵字有著至關重要的作用,在面試中也常常會是必備的一個問題。本文將會介紹volatile關鍵字的作用以及其實現(xiàn)原理。

volatile作用

volatile在并發(fā)編程中扮演著重要的角色,volatile是輕量級的synchronized,volatile關鍵字有兩個作用:

1)保證共享變量的可見性

可見性的意思是當一個線程修改一個共享變量時,另外一個線程能讀到這個修改的值。筆者此前一篇文章Java并發(fā)編程:Java內存模型JMM中有說到,Java內存模型中有主內存和本地內存之分,本地內存持有共享變量的一份副本,線程對共享變量的修改是先修改本地內存的副本,然后再回寫到主內存中去。

可能存在這樣的情況,線程A和線程B同時去修改一個共享變量C,假設線程A先對共享變量C做了修改,而此時線程B卻沒能及時感知到共享變量C已經發(fā)生了改變,緊接著B對本地過期的副本數(shù)據(jù)進行了修改,這造成了共享變量的不可見問題。

而使用了volatile關鍵字修改的共享變量,當線程修改了共享變量之后,會立馬刷新到主內存中,并且會使其他線程緩存了該地址的數(shù)據(jù)失效,這就保證了線程之間共享變量的可見性。

2)防止指令重排序

volatile關鍵字的另外一個作用就是防止指令重排序。代碼在實際執(zhí)行過程中,并不全是按照編寫的順序進行執(zhí)行的,在保證單線程執(zhí)行結果不變的情況下,編譯器或者CPU可能會對指令進行重排序,以提高程序的執(zhí)行效率。但是在多線程的情況下,指令重排序可能會造成一些問題,最常見的就是雙重校驗鎖單例模式:

  1. public class SingletonSafe { 
  2.  
  3.    private static volatile SingletonSafe singleton; 
  4.  
  5.    private SingletonSafe() { 
  6.   } 
  7.  
  8.    public static SingletonSafe getSingleton() { 
  9.        if (singleton == null) { 
  10.            synchronized (SingletonSafe.class) { 
  11.                if (singleton == null) { 
  12.                    singleton = new SingletonSafe(); 
  13.               } 
  14.           } 
  15.       } 
  16.        return singleton; 
  17.   } 

如果沒有使用volatile關鍵字,則可能會出現(xiàn)其他線程獲取了一個未初始化完成的singleton對象,具體原因筆者不在這里贅述了,有興趣的同學可以搜索一下“double checked locking with delay initialization”學習下,筆者后續(xù)有時間再寫篇文章分析下。

volatile實現(xiàn)原理

1)可見性實現(xiàn)原理

對于volatile關鍵字修飾的變量,當對volatile變量進行寫操作的時候,JVM會向處理器發(fā)送一條lock前綴的指令,將這個緩存中的變量回寫到系統(tǒng)主存中。但是就算寫回到內存,如果其他處理器緩存的值還是舊的,再執(zhí)行計算操作就會有問題,所以在多處理器下,為了保證各個處理器的緩存是一致的,就會實現(xiàn)緩存一致性協(xié)議。

緩存一致性協(xié)議:每個處理器通過嗅探在總線上傳播的數(shù)據(jù)來檢查自己緩存的值是不是過期了,當處理器發(fā)現(xiàn)自己緩存行對應的內存地址被修改,就會將當前處理器的緩存行設置成無效狀態(tài),當處理器要對這個數(shù)據(jù)進行修改操作的時候,會強制重新從系統(tǒng)內存里把數(shù)據(jù)讀到處理器緩存里。

所以,如果一個變量被volatile所修飾的話,在每次數(shù)據(jù)變化之后,其值都會被強制刷入主存。而其他處理器的緩存由于遵守了緩存一致性協(xié)議,也會把這個變量的值從主存加載到自己的緩存中。這就保證了一個volatile在并發(fā)編程中,其值在多個緩存中是可見的。

2)防止指令重排序實現(xiàn)原理

volatile防止指令重排序是通過內存屏障來實現(xiàn)的。內存屏障分為如下三種:

Store Barrier

Store屏障,是x86的”sfence“指令,強制所有在store屏障指令之前的store指令,都在該store屏障指令執(zhí)行之前被執(zhí)行。

Load Barrier

Load屏障,是x86上的”ifence“指令,強制所有在load屏障指令之后的load指令,都在該load屏障指令執(zhí)行之后被執(zhí)行

Full Barrier

Full屏障,是x86上的”mfence“指令,復合了load和save屏障的功能。

Java內存模型中volatile變量在寫操作之后會插入一個store屏障,在讀操作之前會插入一個load屏障。一個類的final字段會在初始化后插入一個store屏障,來確保final字段在構造函數(shù)初始化完成并可被使用時可見。也正是JMM在volatile變量讀寫前后都插入了內存屏障指令,進而保證了指令的順序執(zhí)行。

責任編輯:華軒 來源: Happyjava
相關推薦

2022-06-29 08:05:25

Volatile關鍵字類型

2020-11-11 08:45:48

Java

2023-10-04 00:04:00

C++extern

2023-09-24 13:58:20

C++1auto

2024-02-26 10:36:59

C++開發(fā)關鍵字

2012-03-01 12:50:03

Java

2025-06-13 08:00:00

Java并發(fā)編程volatile

2011-06-14 13:26:27

volatile

2011-06-21 09:50:51

volatile

2024-11-20 15:55:57

線程Java開發(fā)

2018-01-19 10:43:06

Java面試官volatile關鍵字

2009-06-29 18:14:23

Java多線程volatile關鍵字

2022-08-17 07:53:10

Volatile關鍵字原子性

2020-07-17 20:15:03

架構JMMvolatile

2024-03-15 08:18:25

volatileAtomic關鍵字

2016-09-19 21:53:30

Java并發(fā)編程解析volatile

2023-11-20 22:19:10

C++static

2023-06-26 08:02:34

JSR重排序volatile

2011-07-14 23:14:42

C++static

2022-02-08 08:31:52

const關鍵字C語言
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产成人jvid在线播放 | 中文字幕不卡在线观看 | 国产精品国产成人国产三级 | 国产激情在线 | 欧美成人不卡 | 精国产品一区二区三区四季综 | 伊人亚洲 | 日韩一区二区三区av | 超碰成人av | 日韩精品一区二区久久 | 粉嫩粉嫩芽的虎白女18在线视频 | 国产一区二区中文字幕 | 国产一区二区毛片 | 国产精品久久久久久妇女 | 99热在线观看精品 | 999久久久久久久久6666 | 亚洲97| 91高清视频在线观看 | 天天综合网7799精品 | 欧美日韩亚洲视频 | 99精品久久99久久久久 | 国产一二三视频在线观看 | 国产精品久久久久久久粉嫩 | 国产日韩精品久久 | 婷婷免费在线 | 日韩在线观看一区 | 成人伊人网 | 日本久久网| 亚洲国产精品一区 | 国产一区二区三区精品久久久 | 中文字幕免费在线观看 | 国产一级片久久久 | 久久综合激情 | 午夜在线观看免费 | 久久精品一区 | 亚洲一区二区三区四区五区午夜 | 欧美性久久 | 色婷婷综合久久久中字幕精品久久 | 久久青视频 | 青草青草久热精品视频在线观看 | 久久亚洲一区 |