什麼是可見性?多線程
在我理解就是多線程下,當一個線程修改共享變量時,其餘線程可以及時的獲得修改的值,此爲可見性。jvm
具體的描述下,線程1,2啓動後,從主內存讀取值x=0,而後以副本的形式存到各自線程的工做內存中。而後線程1的x=1後,若是線程2在使用x的時候能從新從主內存中讀取x=1,那麼這就是可見性。線程
那麼咱們確定須要必定的手段來保證這個順序(工做內存1 - 主內存 - 工做內存2),排序
如何保證?內存
1,線程在修改共享變量後,須要及時回刷主存it
2,其餘線程在使用共享變量時,副本變量應被清空,去主內存從新讀取。變量
那麼如何作到?原理
jvm的內置鎖,synchronized程序
synchronized原理是,解鎖前,將共享變量回刷主存,在加鎖時清空工做內存的共享變量,去主存從新讀取。同時加鎖避免了指令重排序致使的問題。方法
那麼既然加鎖,那麼首先程序已經變成了串行,那麼很好理解可見性。可是jvm還提供了一種輕量級的變量修飾符volitile(不能保證非原子性的操做)
可是其實還有一個更輕量級的修飾符volatile
他也能夠保證內存的可見性(只支持原子操做,不支持複雜操做如i++),他的原理主要靠的是內存屏障
當讀volitile變量時,加一條load屏障,讓副本的變量失效
當寫volitile變量時,會加一條store屏障,讓變量直接回刷主存,不會等到方法結束