三、volatile

特征

被volatile修飾的變量野建,具有兩個(gè)特征

  1. 保證可見性
  2. 不保證原子性
  3. 禁止指令重排序

關(guān)于內(nèi)存可見性属划、原子性、有序性候生,先來了解一下內(nèi)存模型吧~

java內(nèi)存模型(JMM)

  • JMM定義了線程和主內(nèi)存之間的抽相關(guān)
    • 每個(gè)線程都會(huì)有一個(gè)私有的本地內(nèi)存同眯,存儲(chǔ)了共享變量的副本
    • 共享變量存儲(chǔ)再主內(nèi)存中
    • image
特性
  • 原子性
    • 一個(gè)操作要么全部執(zhí)行并且執(zhí)行的過程不會(huì)被打斷,要么就不執(zhí)行(有點(diǎn)像事務(wù))
    • 下面舉個(gè)例子
i = 0;  //是原子操作         
j = i ; //不是唯鸭! 包含兩個(gè)操作 1.讀取i 2.賦值給j
i++;    //不是须蜗!三個(gè)操作 1.讀取i 2.+1 3.賦值給i 

volatile是無(wú)法保證復(fù)合操作的原子性。想在多線程環(huán)境下保證原子性目溉,可以通過鎖明肮、synchronized來確保

  • 可見性
    • 多線程訪問一個(gè)變量時(shí),一個(gè)線程修改變量的值缭付,其他線程能立即看到柿估。
    • 但是,多線程環(huán)境下陷猫,一個(gè)線程修改變量對(duì)其他線程是不可見的秫舌!

volatile可以保證可見性。當(dāng)一個(gè)變量被volatile修飾之后烙丛,該變量被修改后立即更新到內(nèi)存中,讀取的時(shí)候會(huì)直接從內(nèi)存中讀取羔味。

  • 有序性
    • 執(zhí)行的順序按照代碼的先后順序執(zhí)行
    • 在java內(nèi)存模型中河咽,為了效率,是允許處理器對(duì)指令進(jìn)行重排序的

volatile禁止指令重排序赋元,來保證一定的有序性

指令重排序:是JVM為了優(yōu)化指令忘蟹,提高程序運(yùn)行效率,在不影響單線程程序執(zhí)行結(jié)果的前提下搁凸,盡可能地提高并行度媚值。注意是單線程,多線程情況下會(huì)有問題啊

原理

在jvm底層 是采用‘內(nèi)存屏障’來實(shí)現(xiàn)的

  • 內(nèi)存屏障 (Memory Barrier)

    • 又叫內(nèi)存柵欄护糖,是一個(gè)cpu指令
    • 插入一條MB褥芒,會(huì)告訴編譯器和cpu,什么指令都不能和這條MB指令重排序
    • MB會(huì)強(qiáng)制刷出各種CPU cache,如一個(gè)Write-Barrier將刷出所有再Barrier之前寫入cache的數(shù)據(jù)嫡良,因此cpu上的線程都能讀取到這些數(shù)據(jù)的最新版本
  • ****如果一個(gè)變量是volatile修飾的锰扶,JMM會(huì)再寫入這個(gè)字段之后插入Write-Barrier指令,在讀這個(gè)字段之前插入Read-Barrier指令****寝受,意味著:

    • 一個(gè)線程寫入變量A后坷牛,任何線程都可以拿到最新值
  • happens-before

    • 兩個(gè)操作間具有h-b關(guān)系,并不以為著前一個(gè)操作必須要在后一個(gè)操作之前執(zhí)行很澄。
    • 僅僅要求前一個(gè)操作的執(zhí)行結(jié)果京闰,對(duì)后一個(gè)操作可見颜及。且前一個(gè)操作按順序排在后一個(gè)操作之前。

應(yīng)用場(chǎng)景

  • 狀態(tài)量標(biāo)記
int a = 0;
//修改后立刻對(duì)線程可見 比sync lock有一定的效率提升
volatile bool flag = false;

public void write() {
    a = 2;              //1
    flag = true;        //2
}

public void multiply() {
    if (flag) {         //3
        int ret = a * a;//4
    }
}
  • 單例模式的實(shí)現(xiàn) 雙重檢查鎖定(DCL)
懶漢模式
class Singleton{
//為了避免初始化操作的指令重排序 
    private volatile static Singleton instance = null;
 
    private Singleton() {
 
    }
 
    public static Singleton getInstance() {
        if(instance==null) { //B
            synchronized (Singleton.class) {
                if(instance==null)
//在Singleton構(gòu)造函數(shù)體執(zhí)行之前蹂楣,變量instance可能成為非null俏站!
                    instance = new Singleton(); //A
            }
        }
        return instance;
    }
}
1.線程1進(jìn)入到//A處,但在構(gòu)造函數(shù)執(zhí)行之前捐迫。使實(shí)例成為非null
2.線程2進(jìn)入//B處乾翔,實(shí)例不為null,將instance引用返回施戴。返回了一個(gè)構(gòu)造完整但部分初始化的singleton對(duì)象
  • 獨(dú)立觀察 獲取最近一次登錄的用戶名
 public volatile String lastUser; //發(fā)布的信息
 
    public boolean authenticate(String user, String password) {
        boolean valid = passwordIsValid(user, password);
        if (valid) {
            User u = new User();
            activeUsers.add(u);
            lastUser = user;
        }
        return valid;
    }

  • 開銷較低的 ‘讀-寫鎖’策略
private volatile int value;
 
    //讀操作反浓,沒有synchronized,提高性能
    public int getValue() { 
        return value; 
    } 
 
    //寫操作赞哗,必須synchronized雷则。因?yàn)閤++不是原子操作
    public synchronized int increment() {
        return value++;
    }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市肪笋,隨后出現(xiàn)的幾起案子月劈,更是在濱河造成了極大的恐慌,老刑警劉巖藤乙,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猜揪,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡坛梁,警方通過查閱死者的電腦和手機(jī)而姐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來划咐,“玉大人拴念,你說我怎么就攤上這事『植” “怎么了政鼠?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)队魏。 經(jīng)常有香客問我公般,道長(zhǎng),這世上最難降的妖魔是什么胡桨? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任俐载,我火速辦了婚禮,結(jié)果婚禮上登失,老公的妹妹穿的比我還像新娘遏佣。我一直安慰自己,他們只是感情好揽浙,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布状婶。 她就那樣靜靜地躺著意敛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪膛虫。 梳的紋絲不亂的頭發(fā)上草姻,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音稍刀,去河邊找鬼撩独。 笑死,一個(gè)胖子當(dāng)著我的面吹牛账月,可吹牛的內(nèi)容都是我干的综膀。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼局齿,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼剧劝!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起抓歼,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤讥此,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后谣妻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體萄喳,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年蹋半,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了他巨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡湃窍,死狀恐怖闻蛀,靈堂內(nèi)的尸體忽然破棺而出匪傍,到底是詐尸還是另有隱情您市,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布役衡,位于F島的核電站茵休,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏手蝎。R本人自食惡果不足惜榕莺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望棵介。 院中可真熱鬧钉鸯,春花似錦、人聲如沸邮辽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至岩睁,卻和暖如春钞脂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捕儒。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工冰啃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人刘莹。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓阎毅,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親栋猖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子净薛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

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

  • 本文是我自己在秋招復(fù)習(xí)時(shí)的讀書筆記,整理的知識(shí)點(diǎn)蒲拉,也是為了防止忘記肃拜,尊重勞動(dòng)成果,轉(zhuǎn)載注明出處哦雌团!如果你也喜歡燃领,那...
    波波波先森閱讀 11,273評(píng)論 4 56
  • https://blog.csdn.net/javazejian/article/details/72772461...
    楊傳池chris閱讀 1,962評(píng)論 0 17
  • 你要明白任何人的忽冷忽熱 也要習(xí)慣往來者的漸行漸遠(yuǎn) 后來,于誰(shuí)都沒什么好可惜的 有些人愛的太快 有些人愛的太滿 有...
    seayo下午茶閱讀 480評(píng)論 0 0
  • 來阿里實(shí)習(xí)一個(gè)多月了锦援,還沒有寫過自己的感受猛蔽,還是留下幾筆,以后方便回憶灵寺。 與大多數(shù)立志做一名程序員的同學(xué)一樣曼库,在來...
    花少lin閱讀 630評(píng)論 3 2
  • 有一段時(shí)間,整個(gè)人像只剩下軀殼略板,丟了靈魂毁枯。而靈魂處在自我否定當(dāng)中,身邊的同學(xué)叮称、朋友种玛、同事,一個(gè)個(gè)在錯(cuò)覺中疏遠(yuǎn)瓤檐,雖然...
    切爾斯泰閱讀 273評(píng)論 0 0