1. 程式人生 > 其它 >python筆記:#001#python簡介

python筆記:#001#python簡介

synchronized 關鍵字是鎖的一種實現

class X {
  // 修飾非靜態方法
  // 當修飾非靜態方法的時候,鎖定的是當前例項物件 this
  synchronized void foo() {
    // 臨界區
  }
  // 修飾靜態方法 
  // 當修飾靜態方法的時候,鎖定的是當前類的 Class 物件
  synchronized static void bar() {
    // 臨界區
  }
  // 修飾程式碼塊
  Object obj = new Object();
  void baz() {
    synchronized(obj) {
      // 臨界區
      // 鎖定obj 物件
    }
  }
}  
  • 當修飾非靜態方法的時候,鎖定的是當前例項物件 this
  • 當修飾靜態方法的時候,鎖定的是當前類的 Class 物件
  • 當修飾程式碼塊的時候,鎖定的是傳入的物件

加鎖 lock() 和解鎖 unlock() 是被 Java 默默加上的,Java 編譯器會在 synchronized 修飾的方法或程式碼塊前後自動加上加鎖 lock() 和解鎖 unlock()

class SafeCalc {
  long value = 0L;
  synchronized long get() {
    return value;
  }
  synchronized void addOne() {
    value += 1;
  }
}

把 value 改成靜態變數,把 addOne() 方法改成靜態方法

class SafeCalc {
  static long value = 0L;
  synchronized long get() {
    return value;
  }
  synchronized static void addOne() {
    value += 1;
  }
}

改動後的程式碼是用兩個鎖保護一個資源。這個受保護的資源就是靜態變數 value,兩個鎖分別是 this 和 SafeCalc.class

由於臨界區 get() 和 addOne() 是用兩個鎖保護的,因此這兩個臨界區沒有互斥關係,臨界區 addOne() 對 value 的修改對臨界區 get() 也沒有可見性保證,這就會導致併發問題了

class SafeCalc {
  long value = 0L;
  long get() {
    synchronized (new Object()) {
      return value;
    }
  }
  void addOne() {
    synchronized (new Object()) {
      value += 1;
    }
  }
}

可以用一把鎖來保護多個資源,但是不能用多把鎖來保護一個資源

用不同的鎖對受保護資源進行精細化管理,能夠提升效能。叫細粒度鎖

  • 如果資源之間沒有關係,很好處理,每個資源一把鎖就可以了。
  • 如果資源之間有關聯關係,就要選擇一個粒度更大的鎖,這個鎖應該能夠覆蓋所有相關的資源。