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

Java 執行緒安全核心:同步機制、鎖優化與無鎖思路實戰解析

     編輯:Java 相關知識

執行緒安全本質

多執行緒同時存取**共享可變狀態**(臨界資源)導致資料競爭。核心目標:**保證操作原子性、可見性、有序性**。典型場景:資金轉帳、庫存扣減、資料庫事務。

三種同步寫法對比

基礎場景:兩執行緒輪流列印名稱

class Output {
    public void print(String name) {
        for (char c : name.toCharArray()) System.out.print(c);
        System.out.println();
    }
}
// 無同步 → 輸出交錯:zhangsanluxiaofeng...

1. 同步代碼塊

public void print(String name) {
    synchronized (this) {               // 鎖住當前實例
        for (char c : name.toCharArray()) System.out.print(c);
        System.out.println();
    }
}

2. 同步實例方法

public synchronized void print(String name) { // 等同於 synchronized(this)
    for (char c : name.toCharArray()) System.out.print(c);
    System.out.println();
}

3. 同步靜態方法

public static synchronized void print2(String name) {
    // 鎖為 Class 物件:Output.class
    for (char c : name.toCharArray()) System.out.print(c);
    System.out.println();
}

關鍵差異:實例方法鎖 `this`,靜態方法鎖 `Class` 物件。若同時存取同一實例的實例/靜態同步方法,**互不阻塞**(鎖不同),需統一鎖物件。

進階鎖優化策略

細化鎖粒度

class FineGrained {
    private final Object lock1 = new Object();
    private final Object lock2 = new Object();
    private int count1, count2;

    public void inc1() { synchronized(lock1) { count1++; } }
    public void inc2() { synchronized(lock2) { count2++; } }
}

不同資料用不同鎖,提升並發度。

讀寫鎖

private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
public void read()  { rwLock.readLock().lock();  try { ... } finally { rwLock.readLock().unlock(); } }
public void write() { rwLock.writeLock().lock(); try { ... } finally { rwLock.writeLock().unlock(); } }

讀讀並發、讀寫互斥、寫寫互斥,適合「讀多寫少」場景。

無鎖:ThreadLocal / CAS / Immutable

  • ThreadLocal:執行緒獨享副本,零競爭
  • AtomicInteger 等 CAS 類:硬體級原子操作
  • 不可變物件:`final` 欄位、無 setter,天生執行緒安全

常見坑與避坑指南

坑後果修正
用 String 常量/基本型別包裝類作鎖全 JVM 共享同一把鎖,誤阻塞無關代碼用 `private final Object lock = new Object()`
同步方法中調用異步/耗時操作長時間持有鎖,吞吐率暴跌縮小同步範圍,耗時操作移出同步塊
Double-Checked Locking 未加 volatile指令重排導致單例失效`private static volatile Instance inst`
集合迭代時併發修改ConcurrentModificationException用 CopyOnWriteArrayList、ConcurrentHashMap 或同步迭代

總結

  1. **同步代碼塊 > 同步方法 > 同步靜態方法**(靈活度遞減)
  2. 鎖物件必須是**共享、不可變、非公開**的實例
  3. 優先考慮 **JUC 並發容器/鎖/原子類**,減少手寫同步
  4. 能用無鎖(ThreadLocal、不可變、CAS)就不用鎖
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved