多線(xiàn)程可能對(duì)應(yīng)著多個(gè) CPU团赁,多個(gè) CPU 對(duì)應(yīng)著多套緩存(L1, L2, L3, 寄存器)栗柒。緩存的數(shù)據(jù)可能和內(nèi)存的不一致孔庭。 volatile 是為了解決不一致(同步)的問(wèn)題趣些。在讀一個(gè) volatile 變量的時(shí)候會(huì)直接去內(nèi)存讀,寫(xiě)時(shí)會(huì)馬上更新到內(nèi)存臊泌。
The Java volatile Happens-Before Guarantee[1]
When a thread writes to a volatile variable, then not just the volatile variable itself is written to main memory. Also all other variables changed by the thread before writing to the volatile variable are also flushed to main memory. When a thread reads a volatile variable it will also read all other variables from main memory which were flushed to main memory together with the volatile variable.
Java 5 之后增加了這個(gè)規(guī)則鲤桥,這樣就不需要把每個(gè)需要可見(jiàn)的變量聲明為 volatile,只需要在 volatile 的變量更新前更新即可渠概。
對(duì)性能的影響
Reading and writing of volatile variables causes the variable to be read or written to main memory. Reading from and writing to main memory is more expensive than accessing the CPU cache. Accessing volatile variables also prevent instruction reordering which is a normal performance enhancement technique. Thus, you should only use volatile variables when you really need to enforce visibility of variables.
與鎖和 synchronized 的區(qū)別和聯(lián)系
鎖和 synchronized 是為了保證關(guān)鍵區(qū)的原子性茶凳,隱含了可見(jiàn)性(即在關(guān)鍵區(qū)內(nèi)讀應(yīng)該也是從內(nèi)存讀,離開(kāi)關(guān)鍵區(qū)會(huì)把更新刷新到內(nèi)存)來(lái)保證同步播揪。