天天看點

【同步】volatile關鍵字

volatile是一種比sychronized關鍵字更輕量級的同步機制

通路volitile變量時,不會執行加鎖操作

通路非volitile變量時,每個線程會從系統記憶體(主記憶體)拷貝變量到工作記憶體中,然後修改工作記憶體中的變量值,操控的變量可能不同,造成混亂。

volatile修飾的變量,是直接拿的主記憶體的值,就是說這個值永遠是最新的,對其他線程是可見的。

volatile的讀寫操作是原子性的。voalile變量進行頻繁的++操作,就會失去原子性。假如線程A和線程B,同時對0進行++操作100次,結果可能小于200.

使用volitile之後,有兩個特性:

保證此變量對多個線程的可見性,當某一個線程修改了變量,新值會立即同步到主記憶體;

禁止指令重排序,記憶體屏障(保證讀和寫的原子性,不能被任何其他操作打斷):讀-LoadLoad-LoadStore;SotreStore-寫-StoreLoad。

LoadLoad:後面的讀和前面的讀,不會重排序

LoadStore:後面的寫和前面的讀,不會重排序

StoreStore:前面的寫和後面的寫,不會重排序

StoreLoad:後面的讀和前面的寫,不會重排序

寫完修改了工作記憶體中的變量,然後把這個變量指派到主記憶體;通知舊值失效(緩存(工作記憶體)失效)。

什麼叫作緩存失效機制?

定義一個volatile boolean flag = false;

第一個線程進行寫操作,run{while(!flag){System.out.println("一直列印...")}},5秒後(Thread.sleep(5000)),将flag指派為true;

第二個線程,讀到的flag==fasle,那麼也會一直列印,如果此時看到flag已經是true了,這個時候,此線程中的工作記憶體變量(flag==false),會失效。

如果沒有采用緩存失效機制,那麼線程得到的flag值,不具備時效性,會列印多餘的内容,影響結果。

10分鐘學會volatile視訊位址(點選進入)

繼續閱讀