volatile : JVM提供的輕量級(jí)同步機(jī)制
?保證被volatile修飾的共享變量對(duì)所有線程總是可見(jiàn)的,當(dāng)一個(gè)線程修改了被volatile修飾的共享變量的值逝薪,其他線程立即感知到變動(dòng)
?禁止指令重排序優(yōu)化
volatile變量為何立即可見(jiàn)?
- 當(dāng)寫一個(gè)volatile變量時(shí), JMM會(huì)把該線程對(duì)應(yīng)的工作內(nèi)存中的共享變
量值刷新到主內(nèi)存中; - 當(dāng)讀取一個(gè)volatile變量時(shí), JMM會(huì)把該線程對(duì)應(yīng)的工作內(nèi)存置為無(wú)效催式。
volatile如何禁止重排優(yōu)化
內(nèi)存屏障( Memory Barrier )
1.保證特定操作的執(zhí)行順序
2.保證某些變量的內(nèi)存可見(jiàn)性
通過(guò)插入內(nèi)存屏障指令禁止在內(nèi)存屏障前后的指令執(zhí)行重排序優(yōu)化強(qiáng)制刷出各種CPU的緩存數(shù)據(jù),因此任何CPU_上的線程都能讀取到這些數(shù)據(jù)的最新版本
volatile和synchronized的區(qū)別
- volatile本質(zhì)是在告訴JVM當(dāng)前變量在寄存器(工作內(nèi)存)中的值是不確定的,需要從主存中讀取; synchronized則是鎖定當(dāng)前變量, 只有當(dāng)前線程可以訪問(wèn)該變量,其他線程被阻塞住直到該線程完成變量操作為止
- volatile僅能使用在變量級(jí)別; synchronized則可以使用在變量、方法和類級(jí)別
- volatile僅能實(shí)現(xiàn)變量的修改可見(jiàn)性,不能保證原子性;而synchronized則可以保證變量修改的可見(jiàn)性和原子性
- volatile不會(huì)造成線程的阻塞; synchronized可能會(huì)造成線程的阻塞
- volatile標(biāo)記的變量不會(huì)被編譯器優(yōu)化; synchronized標(biāo)記的變量可以被編譯器優(yōu)化