1. 讓我們首先了解下java 中 Volatile 關鍵字
Volatile可實現java內存模型當中的可見性,
java內存模型的可見性:
可見性,是指線程之間的可見性,一個線程修改的狀態對另一個線程是可見的。也就是一個線程修改的結果,另一個線程馬上就能看到。
比如:用volatile修飾的變量,就會具有可見性。volatile修飾的變量不允許線程內部緩存和重排序,即直接修改內存。所以對其他線程是可見的。
BUT
Volatile 不保證原子性:
just like this:
volatile int a=0; a 具有可見性 但是如下操作仍然不具有原子性 a++;
讓我們看看什么是原子操作 什么是非原子操作:
原子操作:a=0;
非原子操作 a++,即a=a+1;
那么在java 中 如何保證原子性呢?方法是 sync ,lock,unlock
2 .那么volatile的實現原理是什么?
先這樣理解:
把對volatile變量的單個讀/寫,看成是使用同一個鎖對這些單個讀/寫操作 做了同步。示例:

示例程序
下面的程序等價於上面的示例程序

等價程序
volatile的特性:
(1) 對一個volatile變量的單個讀/寫操作,與對一個普通變量的讀/寫操作使用同一個鎖來同步,它們之間的執行效果相同。
可見性:對一個volatile變量的讀,總是能看到(任意線程)對這個volatile變量最后的寫入。
原子性:對任意單個volatile變量的讀/寫具有原子性,但類似於volatile++這種復合操作不具有原子性。
3:來談談-------鎖
3.1:釋放鎖和獲取鎖的內存語義
當線程釋放鎖時,JMM會把該線程對應的本地內存中的共享變量刷新到主內存中,示例代碼如下:

code
假設線程A執行writer()方法,隨后線程B執行reader()方法。
整個的執行過程如下:threadA(1->2->3)->threadB(4->5->6)
根據happen-before原則:3執行前的所有A線程的操作在3執行成功后對4以后的流程立即可見
鎖釋放和鎖獲取的內存意義:當線程釋放鎖時,JMM會把該線程對應的本地內存中的變量刷新到主內存中。
當線程獲取共享變量時,會把本地內存中的變量設置為無效,
從而使得被監控的臨界區中的代碼必須去主內存中去讀取共享變量。
4:那就來看看 atomic operation,原子操作不需要sync:
作者:銅雀春深鎖不住
鏈接:https://www.jianshu.com/p/5195f7f742a8
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。