volatile的可見性和有序性

什么是volatile的可見性?

首先要從JMM內(nèi)存模型說起,每一個(gè)線程都會(huì)有自己的工作內(nèi)存,而線程要訪問主內(nèi)存的共享變量時(shí),是會(huì)將變量對(duì)象拷貝一份變量副本到工作內(nèi)存。

對(duì)于普通共享變量,線程讀取的變量值是工作內(nèi)存的副本,修改后并非立即寫入主內(nèi)存,因此在多線程并發(fā)的情況,一個(gè)線程修改了變量值后,另一個(gè)線程可能依然讀取的是自己工作內(nèi)存的變量副本,而沒有讀到另一個(gè)線程修改后的變量值。因此就會(huì)造成并發(fā)情況下出現(xiàn)邏輯控制上的問題。

對(duì)于volatile修飾的變量,線程在修改工作內(nèi)存的變量副本時(shí),會(huì)置其他線程工作內(nèi)存中該變量副本為無效,并在修改后立即寫入主內(nèi)存。而其他線程在發(fā)現(xiàn)工作內(nèi)存中變量副本置為無效時(shí)會(huì)去主內(nèi)存讀取最新的值,這個(gè)過程會(huì)去等待修改線程先寫入主內(nèi)存。因此volatile修飾變量后,線程的讀寫效率會(huì)降低。

volatile修飾變量后,可能引入的問題:因?yàn)関olatile修飾后,變量修改后會(huì)立即寫入到主內(nèi)存。所以可能存在一個(gè)線程內(nèi)已經(jīng)對(duì)該變量判空,但是因?yàn)榱硪粋€(gè)線程置空,導(dǎo)致本線程更容易發(fā)生空指針異常。

volatile A a = new A();

線程1

a = null;

線程2

if(a != null){

a.b();// 可能空指針異常

}

什么是volatile的有序性?

說到有序性就不得不說說指令重排序,什么是指令重排序?簡單的說就是系統(tǒng)為了優(yōu)化代碼執(zhí)行效率,會(huì)打亂代碼先后順序并可能先執(zhí)行后面的代碼。
舉個(gè)例子:

int a=1; // 代碼1
int b =2;// 代碼2
int c =a+b; // 代碼3

代碼2可能會(huì)比代碼1先執(zhí)行,但是代碼3不會(huì)比前面的先執(zhí)行,因?yàn)檫@樣會(huì)出錯(cuò),代碼3依賴前兩者的結(jié)果。所以系統(tǒng)在保證邏輯正確的情況下會(huì)對(duì)代碼重排序。

而volatile修飾的變量就可以禁止指令重排序。
舉個(gè)例子:

//變量c是volatile類型
int a =1;//代碼1
boolean flag =true; //代碼2
c =2;//代碼3
a =2;//代碼4
flag =false; //代碼5

代碼1和代碼2可能重排序,代碼4和代碼5可能重排序,但是代碼3不會(huì)先于代碼1和2執(zhí)行,也不會(huì)在代碼4和5之后執(zhí)行。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 以上代碼會(huì)重復(fù)運(yùn)行 , 不會(huì)停止。 JMM(java內(nèi)存模型) 若想學(xué)習(xí)好多線程, 那么必須了解一下JMM Jav...
    尼爾君閱讀 1,820評(píng)論 0 2
  • 第6章類文件結(jié)構(gòu) 6.1 概述 6.2 無關(guān)性基石 6.3 Class類文件的結(jié)構(gòu) java虛擬機(jī)不和包括java...
    kennethan閱讀 1,068評(píng)論 0 2
  • Java內(nèi)存區(qū)域 Java虛擬機(jī)在運(yùn)行程序時(shí)會(huì)把其自動(dòng)管理的內(nèi)存劃分為以上幾個(gè)區(qū)域,每個(gè)區(qū)域都有的用途以及創(chuàng)建銷毀...
    架構(gòu)師springboot閱讀 1,917評(píng)論 0 5
  • 除了充分利用計(jì)算機(jī)處理器的能力外,一個(gè)服務(wù)端同時(shí)對(duì)多個(gè)客戶端提供服務(wù)則是另一個(gè)更具體的并發(fā)應(yīng)用場景。衡量一個(gè)服務(wù)性...
    胡二囧閱讀 1,457評(píng)論 0 12
  • 第2章 java并發(fā)機(jī)制的底層實(shí)現(xiàn)原理 Java中所使用的并發(fā)機(jī)制依賴于JVM的實(shí)現(xiàn)和CPU的指令。 2.1 vo...
    kennethan閱讀 1,525評(píng)論 0 2

友情鏈接更多精彩內(nèi)容