1、關鍵字volatile(易變的):html
一、保證了多線程操做的可見性;java
二、可是沒法保證對變量的任何操做都是原子性的(如自增操做);編程
三、禁止指令重排序,能在必定程度上保證有序性;緩存
禁止指令重排序規則:多線程
一、多個volatile操做之間不會重排序;併發
二、多條volatile操做做爲指令段分界點,指令優化重排序只在指令段內部進行,即volatile操做執行時其前面語句都執行完畢,且結果可見;性能
volatile的原理和實現機制:優化
「觀察加入volatile關鍵字和沒有加入volatile關鍵字時所生成的彙編代碼發現,加入volatile關鍵字時,會多出一個lock前綴指令。」——摘自《深刻理解Java虛擬機》spa
lock前綴指令實際上至關於一個內存屏障(也成內存柵欄)線程
多線程操做的可見性:
一、每一個線程都有本身的內存,線程1在運行前會先將stop變量copy一份到本身的內存裏(每一個線程都有本身的work memory, 並且共享一個main memory);
二、線程2修改了stop變量後還沒來得及寫入內存(那麼這個時候是放在哪裏??參見下一條),線程2轉區幹別的事情了;
三、使用volatile關鍵字修飾後的stop變量:
第一:使用volatile關鍵字會強制將修改的值當即寫入主存;
第二:使用volatile關鍵字的話,當線程2進行修改時,會致使線程1的工做內存中緩存變量stop的緩存行無效(反映到硬件層的話,就是CPU的L1或者L2緩存中對應的緩存行無效);
第三:因爲線程1的工做內存中緩存變量stop的緩存行無效,因此線程1再次讀取變量stop的值時會去主存讀取。
synchronized與volatile:
一、synchronized關鍵字是防止多個線程同時執行一段代碼,那麼就會很影響程序執行效率,而volatile關鍵字在某些狀況下性能要優於synchronized;
二、可是要注意volatile關鍵字是沒法替代synchronized關鍵字的,由於volatile關鍵字沒法保證操做的原子性。
synchronize代碼塊執行過程:http://www.2cto.com/kf/201504/389055.html
a.線程得到互斥鎖(monitor)
b.清空工做內存
c.從主內存拷貝共享變量最新的值到工做內存成爲副本
d.執行代碼
e.將修改後的副本的值刷新回主內存中
f.線程釋放鎖
volatile使用場景:
一般來講,使用volatile必須具有如下2個條件:
1)對變量的寫操做不依賴於當前值;
2)該變量沒有包含在具備其餘變量的不變式中;
refer:
一、Java併發編程:volatile關鍵字解析(信息量對我這java半吊子略大,須要重讀幾回,另文章內容正確性也未作判斷)
http://www.cnblogs.com/dolphin0520/p/3920373.html