volatile關(guān)鍵字

volatile 關(guān)鍵字簡介

  • 當多個線程進行操作共享數(shù)據(jù)時卿叽,可以保證內(nèi)存中的數(shù)據(jù)可見。
  • 相較于 synchronized 是一種較為輕量級的同步策略固以。

Java語言提供了一種稍弱的同步機制掂僵,即volatile變量,用來確保將變量的更新操作通知到其他線程昆码。當把變量聲明為volatile類型后气忠,編譯器與運行時都會注意到這個變量是共享的,因此不會將該變量上的操作與其他內(nèi)存操作一起重排序赋咽。volatile變量不會被緩存在寄存器或者對其他處理器不可見的地方旧噪,因此在讀取volatile類型的變量時總會返回最新寫入的值。

在訪問volatile變量時不會執(zhí)行加鎖操作脓匿,因此也就不會使執(zhí)行線程阻塞淘钟,因此volatile變量是一種比sychronized關(guān)鍵字更輕量級的同步機制。

731716-20160708224602686-2141387366.png

當對非 volatile 變量進行讀寫的時候陪毡,每個線程先從內(nèi)存拷貝變量到CPU緩存中米母。如果計算機有多個CPU勾扭,每個線程可能在不同的CPU上被處理,這意味著每個線程可以拷貝到不同的 CPU cache 中铁瞒。

而聲明變量是 volatile 的妙色,JVM 保證了每次讀變量都從內(nèi)存中讀,跳過 CPU cache 這一步慧耍。

當一個變量定義為 volatile 之后身辨,將具備兩種特性:

  • 保證此變量對所有的線程的可見性,即當一個線程修改了這個變量的值芍碧,volatile 保證了新值能立即同步到主內(nèi)存煌珊,以及每次使用前立即從主內(nèi)存刷新。但普通變量做不到這點泌豆,普通變量的值在線程間傳遞均需要通過主內(nèi)存來完成定庵。
  • 禁止指令重排序優(yōu)化。有volatile修飾的變量践美,賦值后多執(zhí)行了一個“l(fā)oad addl $0x0, (%esp)”操作洗贰,這個操作相當于一個內(nèi)存屏障(指令重排序時不能把后面的指令重排序到內(nèi)存屏障之前的位置),只有一個CPU訪問內(nèi)存時陨倡,并不需要內(nèi)存屏障敛滋;(指令重排序:是指CPU采用了允許將多條指令不按程序規(guī)定的順序分開發(fā)送給各相應電路單元處理)。

volatile 性能:

  • volatile 的讀性能消耗與普通變量幾乎相同兴革,但是寫操作稍慢绎晃,因為它需要在本地代碼中插入許多內(nèi)存屏障指令來保證處理器不發(fā)生亂序執(zhí)行。
示例代碼:
public class TestVolatile {
    
    public static void main(String[] args) {
        ThreadDemo td = new ThreadDemo();
        new Thread(td).start();
        
        while(true){
            if(td.isFlag()){
                System.out.println("------------------");
                 break;
            }   
        }
    }
}

class ThreadDemo implements Runnable {

       // 1. 不使用volatile關(guān)鍵字杂曲,子線程修改后變量后(更新子線程緩存庶艾,再更新主內(nèi)存),main線程沒有從主內(nèi)存中讀取擎勘,還是從main線程的緩存中讀取
    private boolean flag = false;

      // 2.使用volatile關(guān)鍵字咱揍,子線程修改后變量后(更新子線程緩存,再更新主內(nèi)存)棚饵,main線程每次跳過自己的緩存煤裙,而是從主內(nèi)存中讀取
      // private volatile boolean flag = false;

    @Override
    public void run() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
        }

        flag = true;
        System.out.println("flag=" + isFlag());
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

}

volatile關(guān)鍵字缺陷

  • volatile 不具備“互斥性”
  • volatile 不能保證變量的“原子性”
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市噪漾,隨后出現(xiàn)的幾起案子硼砰,更是在濱河造成了極大的恐慌,老刑警劉巖欣硼,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件题翰,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機豹障,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門冯事,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人血公,你說我怎么就攤上這事桅咆。” “怎么了坞笙?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長荚虚。 經(jīng)常有香客問我薛夜,道長,這世上最難降的妖魔是什么版述? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任梯澜,我火速辦了婚禮,結(jié)果婚禮上渴析,老公的妹妹穿的比我還像新娘晚伙。我一直安慰自己,他們只是感情好俭茧,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布咆疗。 她就那樣靜靜地躺著,像睡著了一般母债。 火紅的嫁衣襯著肌膚如雪午磁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天毡们,我揣著相機與錄音迅皇,去河邊找鬼。 笑死衙熔,一個胖子當著我的面吹牛登颓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播红氯,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼框咙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了脖隶?” 一聲冷哼從身側(cè)響起扁耐,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎产阱,沒想到半個月后婉称,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年王暗,在試婚紗的時候發(fā)現(xiàn)自己被綠了悔据。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡俗壹,死狀恐怖科汗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绷雏,我是刑警寧澤头滔,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站涎显,受9級特大地震影響坤检,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜期吓,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一早歇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧讨勤,春花似錦箭跳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至脊岳,卻和暖如春逝段,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背割捅。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工奶躯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人亿驾。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓嘹黔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親莫瞬。 傳聞我的和親對象是個殘疾皇子儡蔓,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容