標籤:png 對象 color 用戶端 另一個 成員變數 mem 一個 擷取
1. java的線程間通訊是由java的記憶體模型(JMM)來控制的。
JMM(java memory management) 定義了線程和主記憶體之間的抽象關係,一個是主記憶體(多線程之間來進行共用),一個是每個線程自己的私人記憶體
2. 為什麼需要同步機制?
(1) 同步機制一般發生在多線程中,當需要跨線程維護程式的正確性,當需要多個線程之間共用非final變數時,就必須使用同步機制來保證一個線程的操作對於另一個線程是可見的
(2) 同步機制保證了多個線程之間的可靠通訊,保證了多個線程之間對共用變數的互斥訪問,同步常用的關鍵字是synchronized和volatile
3. 同步和非同步
同步:同步資料時,伺服器不能幹其他的事。例如用戶端提起一個同步請求後,伺服器在同步資料期間不能執行其他的操作
非同步:用戶端提起一個非同步請求後,伺服器在非同步同步資料時依然可以執行其他動作
而java中的同步通常指同步共用資料,或者某個對象或者同步某個方法
4. volatile關鍵字
(1) 成員變數加上volatile後,線程每次訪問成員變數時,都需要首先從共用記憶體中擷取該對象,如果成員變數發生變化,還必須寫回記憶體
(2) 也就是說volatile保證了成員變數的讀寫互斥,相當於一個讀寫鎖
主意:volatile並不能保證多線程操作的原子性,只能保持每次從記憶體拿到的資料是當前最新的
例如:線程A,線程B同時從記憶體拿到一個 public volatile static int count=5 的成員變數,A,B同時操作count = count+1後,A將count=6寫進去,B將count=6寫進去,最後記憶體變數中只會是count=6。
也就是說volatile只是線上程和記憶體之間加了一個鎖,比較線程執行前後成員變數是否改變,而不會控制線程之間的互斥操作。
5. synchronized關鍵字:保證同一時刻只有一個線程在執行synchronized修飾的內容
(1) synchronized 方法
public synchronized void test(){ //method data}
(2) synchronized 塊
public void test(){ synchronized(obj){ //代碼塊,每次只有一個線程可以訪問 }}
雖然一般同步都會介紹synchronized和volatile,但個人感覺volatile有些雞肋,能用volatile的可以用synchronized代替。而且volatile很容易誤導大家想成原子性的
java——同步機制(synchronized, volatile)