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

Java 多線程基礎:synchronized 關鍵字原理與鎖機制全解析

     編輯:Java 相關知識

1. synchronized 原理

Java 中每個對象有且僅有一把同步鎖。調用對象的 synchronized 方法或進入 synchronized 代碼塊即獲取該鎖。鎖訪問互斥:同一時刻只能被一個線程持有,實現多線程對對象/方法的互斥訪問。

2. synchronized 三大基本規則

規則一:同步方法/塊互斥

線程訪問對象的 synchronized 方法/塊時,其他線程訪問該對象的同一方法/塊將被阻塞。

// Demo1_1: 共享 Runnable 實例 -> 共享鎖 -> 串行執行
class MyRunable implements Runnable {
    public void run() {
        synchronized(this) { ... }
    }
}
public class Demo1_1 {
    public static void main(String[] args) {
        Runnable demo = new MyRunable();
        new Thread(demo, "t1").start();
        new Thread(demo, "t2").start(); // t1, t2 共享 demo 實例鎖
    }
}

結果:t1 執行完 5 次循環後,t2 才開始。

規則二:非同步代碼不受影響

線程訪問同步塊時,其他線程仍可訪問該對象的非同步代碼。

// Demo2: t1 調用 synMethod(同步),t2 調用 nonSynMethod(非同步) -> 並發執行
class Count {
    public void synMethod() { synchronized(this) { ... } }
    public void nonSynMethod() { ... } // 無 synchronized
}

結果:t1 和 t2 交替輸出。

規則三:同一對象的所有同步方法/塊互斥

線程訪問對象的某同步方法/塊時,其他線程訪問該對象的其他同步方法/塊也會被阻塞。

// Demo3: 將 nonSynMethod 也加上 synchronized(this) -> 串行執行

3. synchronized 方法 vs 代碼塊

  • 同步方法:public synchronized void foo() { ... },鎖是 this(實例方法)或類對象(靜態方法)。
  • 同步代碼塊:synchronized(obj) { ... },可精確控制鎖的範圍與粒度,通常效率更高。
// Demo4: 性能對比
public synchronized void synMethod() { for(int i=0;i<1000000;i++); }
public void synBlock() { synchronized(this) { for(int i=0;i<1000000;i++); } }
// 結果:synBlock() 耗時通常少於 synMethod()

4. 實例鎖 vs 全局鎖

鎖類型對應形式作用範圍
實例鎖synchronized 修飾實例方法/塊鎖定具體實例對象,單例時等同全局鎖
全局鎖static synchronized 或鎖 .class針對類,所有實例共享

四種鎖組合驗證

class Something {
    public synchronized void isSyncA() {}
    public synchronized void isSyncB() {}
    public static synchronized void cSyncA() {}
    public static synchronized void cSyncB() {}
}
Something x = new Something(), y = new Something();
  1. x.isSyncA() vs x.isSyncB():不能並發(同一實例鎖)。
  2. x.isSyncA() vs y.isSyncA():可並發(不同實例鎖)。
  3. x.cSyncA() vs y.cSyncB():不能並發(共享類鎖)。
  4. x.isSyncA() vs Something.cSyncA():可並發(實例鎖 vs 類鎖)。

每種情況均附有完整代碼與運行結果驗證。

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