顯示具有 synchronized 標籤的文章。 顯示所有文章
顯示具有 synchronized 標籤的文章。 顯示所有文章

2011年4月11日 星期一

JAVA筆記-synchronized 同步物件資料,避免Race Condition

當多執行緒存取一共享變數時,會有race condition問題,
亦即變數產生不一致性的同步問題,
JAVA提供synchronized的方法,利用lock來鎖定物件,
使得在同一時間內最多只能予許一個執行緒存取共享變數

synchronized有兩種撰寫方法:
1. synchronized method
當同時有多個執行緒存取方法時,先到者優先使用,
後到者必須持續等待前一個執行緒執行完離開方法後,
釋放其lock才可進入使用
synchronized method其lock是該類別的lock,
因此如果這個類別擁有兩個以上的同步化方法,
而又有多個執行緒存取該類別不同個的同步化方法,
也是只會只有一個執行緒可以正常進入執行,
其他執行緒仍然必須等待,因為lock是class lock,
鎖住的是一整個類別
public class Sync {
  public synchronized void one(...){...}
  public synchronized void two(...){...}
}

2. synchronizated block
為了減少synchronized過於影響執行效率,所以期望把受影響的範圍縮小,
因此使用其他物件來當lock,但仍然可用class lock,將lock指定為this即可
public void three{
  synchronized (lock) {...}
}


關於static method synchronized,
我的觀念不夠成熟,可能不夠充足與正確,
所以不多闡述,可參考[Java] Synchronized 心得

在所有類別上,同時只有一個執行緒可以執行在synchronized static method;
而對於同一個類別所new出來的instance,
同時只有一個執行緒可以執行它自己的synchronized method(non-static),
因為每一個instance是鎖自己的lock

2010年9月15日 星期三

Java筆記-Deadlock 死結

不當使用synchronized,造成執行緒資源互鎖,程式無法結束 ##ReadMore## public class Deadlock {
  public static main(String[] args) {
    final Object r1 = "r1";
    final Object r2 = "r2";
    Thread t1 = new Thread() {
      public void run() {
        synchronized(r1) {
          System.out.println("T1 : locked r1");
          try {Thread.sleep(150);}
          catch(InterruptedException e) {}
          synchronized(r2) {
            System.out.println("T1 : locked r2");
          }
        }
      }
    };
    Thread t2 = new Thread() {
      public void run() {
        synchronized(r2) {
          System.out.println("T2 : locked r2");
          try {Thread.sleep(50);}
          catch(InterruptedException e) {}
          synchronized(r1) {
            System.out.println("T2 : locked r1");
          }
        }
      }
    };
    t1.start();
    t2.start();
  }
}

結果輸出:(程式無法停止執行)
T1 : locked r1
T2 : locked r2
/