Java併發程式設計的藝術筆記(一)——volatile和syncronized關鍵字
阿新 • • 發佈:2019-01-07
一.執行緒間的通訊
volatile和syncronized關鍵字
volatile 修飾變數,告知任何對該變數的訪問必須從共享記憶體獲取,對它的改變必須同步重新整理至共享記憶體,由此保證可見性。
syncronized修飾方法和同步塊
syncronized的實現細節
寫一個java類:
public class Synchronized { public static void main(String[] args) { // 對Synchronized Class物件進行加鎖 synchronized (Synchronized.class) { } // 靜態同步方法,對Synchronized Class物件進行加鎖m(); } public static synchronized void m() { } }
在class檔案的同級目錄執行 javap –v Synchronized.class,部分相關輸出:
public static void main(java.lang.String[]); // 方法修飾符,表示:public staticflags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=1 0: ldc #1 // class com/murdock/books/multithread/book/Synchronized2: dup 3: monitorenter // monitorenter:監視器進入,獲取鎖 4: monitorexit // monitorexit:監視器退出,釋放鎖 5: invokestatic #16 // Method m:()V 8: return public static synchronized void m(); // 方法修飾符,表示: public static synchronized flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED Code: stack=0, locals=0, args_size=0 0: return
對於同步塊使用 monitorenter ,monitorexit
對於同步方法則依靠方法修飾符上的ACC_SYNCHRONIZED實現的
由此看出,任意一個物件都擁有自己的監視器,當這個物件由同步塊或者這個物件的同步方法呼叫時,執行方法的執行緒必須先獲取到該物件的監視器才能進入同步塊或者同步方法,而沒有獲取到監視器(執行該方法)的執行緒將會被阻塞在同步塊和同步方法的入口處,進入同步佇列,進入BLOCKED狀態。
下圖描述了物件、監視器、同步佇列和執行執行緒的關係: