首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 多線程同步問題探究(二):synchronized 與對象鎖機制

     編輯:Java 相關知識

synchronized 關鍵字與對象鎖

Java 多線程編程中重要關鍵字 synchronized,實際依靠對象鎖機制實現線程同步。許多人困惑:「同步機制靠對象鎖,但關鍵字哪裡鎖住對象?」

錯誤範例:鎖住不同對象

public class ThreadTest extends Thread {
  public synchronized void run() { ... }  // 鎖住 this(每線程不同實例)
}

10 線程各持有自己實例的鎖,必然無同步效果。要同步,線程持有的對象鎖必須共享且唯一!

正確範例 1:共享 String 物件作鎖

public class ThreadTest2 extends Thread {
  private String lock;
  public ThreadTest2(int threadNo, String lock) { this.lock = lock; }
  public void run() {
    synchronized (lock) {  // 所有線程共享同一 String 物件
      for (int i=1; i<10000; i++) System.out.println(...);
    }
  }
  public static void main(String[] args) {
    String lock = new String("lock");
    for (int i=1; i<10; i++) new ThreadTest2(i, lock).start();
  }
}

main 建立一 String 物件,透過構造函數傳給所有線程。Java 傳值特性使所有線程的 lock 變量指向堆中同一區域。同步塊鎖定同一物件 → 線程依序執行,同步生效。

正確範例 2:靜態同步方法用 Class 物件鎖

public class ThreadTest3 extends Thread {
  public static synchronized void abc(int threadNo) { ... }
  public void run() { abc(threadNo); }
}

同步靜態方法的對象鎖是該類的 Class 實例。JVM 中所有被載入類有唯一類對象(本例 ThreadTest3.class),無論建立多少實例,類實例只有一個 → 同步生效。

同步機制總結

同步方式對象鎖生效條件
同步實例方法方法所在對象 (this)單例模式
同步靜態方法類的 Class 物件 (唯一)總是生效
同步代碼塊synchronized(obj) 中的 obj程式設計師指定共享物件
  • 同步塊對象鎖需程式設計師指定,synchronized(this) 僅單例模式生效
  • 同步方法分靜態/非靜態:靜態總同步,非靜態需單例模式,推薦用靜態方法

synchronized 似在說:「給我一把鎖,我能創造一個規矩。」下一篇將介紹 JDK 5 的 java.util.concurrent 框架。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved