007.多執行緒-Java記憶體模型
阿新 • • 發佈:2018-11-15
Java記憶體模型 ( Java Memory Model , JMM )
JMM主要是規定了執行緒與記憶體之間的一些關係。
Java記憶體模型中規定,所有的變數都儲存在主記憶體中,
對所有執行緒都是共享的。
而每個執行緒都有自己的工作記憶體。
工作記憶體中儲存的是對主記憶體中某些變數的拷貝。
不同執行緒無法訪問對方的工作記憶體,
執行緒間通訊必須通過主記憶體來完成。
執行緒對所有變數的操作(讀取、賦值等)必須在工作記憶體中進行,
首先,將變數衝主記憶體拷貝到自己的工作記憶體,
然後,對變數進行操作,操作完成後,再將變數更新到主記憶體。
上圖來源於 https://blog.csdn.net/javazejian/article/details/72772461
執行緒安全問題
當多個執行緒同時操作(讀取+賦值)一個數據的時候,
可能因為工作記憶體沒有及時重新整理到主記憶體 (執行緒何時將工作記憶體重新整理到主記憶體是不確定的),
造成執行緒不安全。
多執行緒的三大特性
-
原子性
-
原子性指的是一個操作是不可中斷的,即使是在多執行緒環境下,一個操作一旦開始就不會被其他執行緒影響
int i=1;//原子操作,直接賦值,要麼賦值成功,要麼賦值不成功 i++;//非原子操作,這裡包含了多步:讀取i的值;將i的值加1;將新值賦值給i
-
-
可見性
-
當多個執行緒訪問同一個變數時,一個執行緒修改了這個變數的值,其他執行緒能夠立即看得到修改的值。
解決可見性問題,一般採用volatile volatile可以保證可見性,但是卻不能保證原子性
public class VolatileSafe { volatile boolean close; public void close(){ close=true; } public void doWork(){ while (!close){ System.out.println("safe...."); } } /** * 由於對於boolean變數close值的修改屬於原子性操作, * [對於非原子性操作,應使用synchronized關鍵字來保證執行緒安全] * 因此可以通過使用volatile修飾變數close, * 使用該變數對其他執行緒立即可見, * 從而達到執行緒安全的目的。 */
-
-
有序性
-
程式執行的順序按照程式碼的先後順序執行。
volatile關鍵字另一個作用就是禁止指令重排優化, 從而避免多執行緒環境下程式出現亂序執行的現象
-