什么是可見性?
一個線程修改了共享變量的值,其他線程也能看到最新修改的值 。
下圖是一段存在線程可見性問題的代碼:

在主線程中修改兩個變量的值,不一定對副線程可見,副線程有可能讀取到為false的ready和為111的num。
為什么會出現這樣的結果?
線程的交叉執行,重排序加線程交叉執行,共享變量更新后的值沒有在工作內存和主內存中及時更新。
首先要對java內存模型有一個大概的概念,每個線程有自己的工作內存,除此之外還有主內存區域,對變量的讀寫不一定會及時寫入到主存,想要對其它線程可見,需要將工作內存中的寫入同步到主存,並且同步到各個線程的工作內存中。

線程對共享變量的讀寫都必須在自己的工作內存中進行,而不能直接在主內存中讀寫。不同線程不能直接訪問其他線程的工作內存中的變量,線程間變量值的傳遞需要主內存作為橋梁。
如何實現可見性?
在被synchronized保護的代碼塊中對共享變量進行寫入,或者使用volatile修飾變量。


需要注意:Volatile通過內存屏障和禁止重排序來實現線程可見性。但不能保證原子性。
