先說說volatile的三個性質吧(過眼也行):
1.可見性蹂随;
2.不保證原子性迅诬;
3.禁止指令重排序奥喻;
再繼續(xù)深入volatile之前,再來談談Java內存模型(JMM)
JMM的三個性質:
1.原子性凌蔬;
2.可見性露懒;
3.有序性闯冷;
這三個性質也是并發(fā)無法避免的問題砂心。
好了回歸正題懈词,繼續(xù)說volatile。
在線程操作共享變量辩诞,即上圖主內存中的變量時坎弯,會先拷貝一份到本線程的工作內存,然后再對其操作译暂。但這樣也帶來一個問題抠忘,就是其中一個線程對這個共享變量修改后,其他線程無法立即感知這個變化外永,仍使用修改前的值進行操作崎脉,那這樣的操作就顯得無意義甚至不安全。
所以使用了volatile來修飾共享變量伯顶,它的作用就是保證了對其他線程的可見性囚灼,原理就是當線程修改共享變量的值的時候,會將該共享變量刷新回主內存祭衩,其他線程立即感知到共享變量已改變灶体,則重寫讀取共享變量的值。進而volatile保證了可見性掐暮。
volatile不保證原子性是因為volatile的底層實現(xiàn)并不是OS中的原語操作(即原子性操作)蝎抽,所以要想保證原子性,可以使用JUC包下的原子類路克。
volatile禁止指令重排的語義:
在執(zhí)行程序時為了提高性能樟结,編譯器和處理器通常會對指令做重排序:
編譯器重排序。編譯器在不改變單線程程序語義的前提下精算,可以重新安排語句的執(zhí)行順序狭吼;
處理器重排序。如果不存在數(shù)據(jù)依賴性殖妇,處理器可以改變語句對應機器指令的執(zhí)行順序刁笙;