內(nèi)容目錄:
volatile在Java內(nèi)存模型(JMM)中,保證共享變量對(duì)所有線(xiàn)程可見(jiàn),但不保證原子性。volatile語(yǔ)義是同步,通過(guò)共享變量的方式,完成線(xiàn)程間的通信。
為什么需要volatile
Java內(nèi)存模型中抽象、簡(jiǎn)化了計(jì)算機(jī)物理設(shè)備,分成工作內(nèi)存和主內(nèi)存,線(xiàn)程有各自的工作內(nèi)存,卻共享主內(nèi)存。如果要把Java內(nèi)存模型與物理設(shè)備映射起來(lái)的話(huà),L1,L2 Cache可以視為工作內(nèi)存,而L3 Cache視為主內(nèi)存。線(xiàn)程執(zhí)行指令時(shí),會(huì)優(yōu)先選擇距離 CPU 較近的位置的工作內(nèi)存中使用,而不會(huì)從讀寫(xiě)速度較慢的主內(nèi)存中,我稱(chēng)之為“就近原則”。當(dāng)線(xiàn)程指令執(zhí)行完后,賦值給工作內(nèi)存,如果不回寫(xiě)到主內(nèi)存,或者通知其他線(xiàn)程,其他線(xiàn)程是無(wú)法知曉變量已經(jīng)修改,仍然會(huì)使用曾經(jīng)緩存在工作內(nèi)存中的變量,這就造成了緩存不一致的問(wèn)題,Java使用volatile解決這種問(wèn)題。volatile保證指令賦值完后的變量立即同步回主內(nèi)存中,聲明并通知其他線(xiàn)程當(dāng)前賦值的變量已經(jīng)失效,其他線(xiàn)程在下次使用時(shí)會(huì)放棄工作內(nèi)存中變量,使用主內(nèi)存中的變量。這樣就完成了線(xiàn)程間對(duì)于volatile修飾的變量的通信。