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

Java 並發新同步機制(二):ReentrantReadWriteLock 讀寫鎖深度實戰

     編輯:Java 相關知識

適用場景:讀多寫少

ReentrantReadWriteLock 針對讀操作遠多於寫操作的場景優化:

  • 讀-讀:共享,多執行緒可同時持有讀鎖。
  • 讀-寫 / 寫-讀 / 寫-寫:互斥,寫鎖獨佔。

核心 API

ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
Lock readLock = rwLock.readLock();   // 共享鎖
Lock writeLock = rwLock.writeLock(); // 獨佔鎖

標準使用模板

// 讀操作
readLock.lock();
try {
    // 讀取共享資料
} finally {
    readLock.unlock();
}

// 寫操作
writeLock.lock();
try {
    // 修改共享資料
} finally {
    writeLock.unlock();
}

完整測試案例:4 讀者 + 1 寫者

public class ReadWriteLockDemo {
    public static String testVal = "Initiation";

    static class Reader extends Thread {
        private final Lock readLock;
        Reader(Lock readLock, String name) { this.readLock = readLock; setName(name); }
        public void run() {
            while (true) {
                readLock.lock();
                try {
                    System.out.println(getName() + ": read - " + testVal);
                } finally { readLock.unlock(); }
                sleep(1000);
            }
        }
    }

    static class Writer extends Thread {
        private final Lock writeLock;
        Writer(Lock writeLock, String name) { this.writeLock = writeLock; setName(name); }
        public void run() {
            while (true) {
                writeLock.lock();
                try {
                    System.out.println(getName() + ": write");
                    testVal = "1111".equals(testVal) ? "2222" : "1111";
                } finally { writeLock.unlock(); }
                sleep(2000);
            }
        }
    }

    public static void main(String[] args) {
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        Lock r = lock.readLock(), w = lock.writeLock();
        new Reader(r, "R1").start();
        new Reader(r, "R2").start();
        new Reader(r, "R3").start();
        new Reader(r, "R4").start();
        new Writer(w, "W1").start();
    }
}

輸出觀察

R1: read - Initiation
R3: read - Initiation      ← 讀-讀並發,同時輸出
W1: write                  ← 寫鎖獨佔,阻塞後續讀/寫
R2: read - 1111
R4: read - 1111
R3: read - 1111
R1: read - 1111
...

可見:寫入期間所有讀者阻塞;寫入完成後,多個讀者再次並發讀取最新值。

進階特性

  • 可重入性:同一執行緒可重複獲取讀/寫鎖(計數器機制)。
  • 鎖降級:持有寫鎖 → 獲取讀鎖 → 釋放寫鎖(不支援升級)。用於寫入後立即讀取一致性快照。
  • 公平/非公平:建構子 new ReentrantReadWriteLock(true) 選擇公平模式(預設非公平,吞吐量更高)。
  • Condition:僅 writeLock 支援 newCondition(),讀鎖不支援等待/通知。

Lock 體系總結:為什麼取代 synchronized?

特性synchronizedLock (ReentrantLock/ReadWriteLock)
API 豐富度無tryLock()、lockInterruptibly()、Condition、公平鎖
多條件變數單一 wait set多個 Condition 實現精準喚醒
鎖範圍控制方法/塊級任意範圍,跨方法鎖定
可中斷性不可中斷lockInterruptibly() 可響應中斷
效能(低競爭)優化後極佳略高開銷
效能(高競爭/讀多寫少)無讀寫分離ReadWriteLock 顯著優勢
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved