成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:說說讀寫鎖實現原理?

開發 前端
ReentrantReadWriteLock(讀寫鎖)是 Java 并發包(java.util.concurrent.locks)中的一個類,它實現了一個可重入的讀寫鎖。讀寫鎖允許多個線程同時讀取共享資源,但在寫入共享資源時只允許一個線程進行。

在實際項目開發中,并發編程一定會用(提升程序的執行效率),而用到并發編程那么鎖機制就一定會用,因為鎖是保證并發編程的主要手段。

在 Java 中常用的鎖有以下幾個:

  • synchronized(內置鎖):Java 語言內置的關鍵字,JVM 層級鎖實現,使用起來較為簡單直觀。
  • ReentrantLock(可重入鎖):需要顯式地獲取和釋放鎖,提供了更靈活的鎖操作方式。
  • ReentrantReadWriteLock(讀寫鎖):性能較好,分為讀鎖和寫鎖,允許多個讀線程同時獲取讀鎖,而寫鎖具有排他性。
  • StampedLock(郵戳鎖):JDK 8 提供的鎖,提供了一種樂觀讀的方式,先嘗試讀取,如果在讀取過程中沒有發生寫操作,則可以直接完成讀取,避免了獲取讀鎖的開銷。

而我們今天重點要討論的是讀寫鎖 ReentrantReadWriteLock 和它的實現原理。

1.讀寫鎖介紹

ReentrantReadWriteLock(讀寫鎖)是 Java 并發包(java.util.concurrent.locks)中的一個類,它實現了一個可重入的讀寫鎖。讀寫鎖允許多個線程同時讀取共享資源,但在寫入共享資源時只允許一個線程進行

它把鎖分為兩部分:讀鎖和寫鎖,其中讀鎖允許多個線程同時獲得,因為讀操作本身是線程安全的,而寫鎖則是互斥鎖,不允許多個線程同時獲得寫鎖,并且寫操作和讀操作也是互斥的。

也就是說讀寫鎖的特征是:

  • 讀-讀操作不加鎖。
  • 讀-寫操作加鎖。
  • 寫-寫操作加鎖。

2.基本使用

ReentrantReadWriteLock 鎖分為以下兩種:

  • ReentrantReadWriteLock.ReadLock 表示讀鎖:它提供了 lock 方法進行加鎖、unlock 方法進行解鎖。
  • ReentrantReadWriteLock.WriteLock 表示寫鎖:它提供了 lock 方法進行加鎖、unlock 方法進行解鎖。

它的基礎使用如下代碼所示:

// 創建讀寫鎖
final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// 獲得讀鎖
final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
// 獲得寫鎖
final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
// 讀鎖使用
readLock.lock();
try {
    // 業務代碼...
} finally {
    readLock.unlock();
}
// 寫鎖使用
writeLock.lock();
try {
    // 業務代碼...
} finally {
    writeLock.unlock();
}

(1)讀讀不互斥

多個線程可以同時獲取到讀鎖,稱之為讀讀不互斥,如下代碼所示:

// 創建讀寫鎖
final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// 創建讀鎖
final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
Thread t1 = new Thread(() -> {
    readLock.lock();
    try {
        System.out.println("[t1]得到讀鎖.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t1]釋放讀鎖.");
        readLock.unlock();
    }
});
t1.start();
Thread t2 = new Thread(() -> {
    readLock.lock();
    try {
        System.out.println("[t2]得到讀鎖.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t2]釋放讀鎖.");
        readLock.unlock();
    }
});
t2.start();

以上程序執行結果如下:

(2)讀寫互斥

讀鎖和寫鎖同時使用是互斥的(也就是不能同時獲得),這稱之為讀寫互斥,如下代碼所示:

// 創建讀寫鎖
final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// 創建讀鎖
final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
// 創建寫鎖
final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
// 使用讀鎖
Thread t1 = new Thread(() -> {
    readLock.lock();
    try {
        System.out.println("[t1]得到讀鎖.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t1]釋放讀鎖.");
        readLock.unlock();
    }
});
t1.start();
// 使用寫鎖
Thread t2 = new Thread(() -> {
    writeLock.lock();
    try {
        System.out.println("[t2]得到寫鎖.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t2]釋放寫鎖.");
        writeLock.unlock();
    }
});
t2.start();

以上程序執行結果如下:

(3)寫寫互斥

多個線程同時使用寫鎖也是互斥的,這稱之為寫寫互斥,如下代碼所示:

// 創建讀寫鎖
final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// 創建寫鎖
final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
Thread t1 = new Thread(() -> {
    writeLock.lock();
    try {
        System.out.println("[t1]得到寫鎖.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t1]釋放寫鎖.");
        writeLock.unlock();
    }
});
t1.start();

Thread t2 = new Thread(() -> {
    writeLock.lock();
    try {
        System.out.println("[t2]得到寫鎖.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t2]釋放寫鎖.");
        writeLock.unlock();
    }
});
t2.start();

以上程序執行結果如下:

(4)優點分析

  1. 提高了程序執行性能:多個讀鎖可以同時執行,相比于普通鎖在任何情況下都要排隊執行來說,讀寫鎖提高了程序的執行性能。
  2. 避免讀到臨時數據:讀鎖和寫鎖是互斥排隊執行的,這樣可以保證了讀取操作不會讀到寫了一半的臨時數據。

(5)適用場景

讀寫鎖適合多讀少寫的業務場景,此時讀寫鎖的優勢最大。

3.底層實現

ReentrantReadWriteLock 是基于 AbstractQueuedSynchronizer(AQS)實現的,AQS 以單個 int 類型的原子變量來表示其狀態,并通過 CAS 操作來保證線程安全。

這點也通過 ReentrantReadWriteLock 源碼發現,ReentrantReadWriteLock 中的公平鎖繼承了 AbstractQueuedSynchronizer(AQS):

而 ReentrantReadWriteLock 中的非公平鎖繼承了公平鎖(公平鎖繼承了 AbstractQueuedSynchronizer):

所以可以看出 ReentrantReadWriteLock 其底層主要是通過 AQS 實現的。

4.AQS

AbstractQueuedSynchronizer(AQS)是 Java 并發包中的一個抽象類,位于 java.util.concurrent.locks 包中。它為實現依賴于“獨占”和“共享”模式的阻塞鎖和相關同步器提供了一個框架。

AQS 是許多高級同步工具的基礎,例如 ReentrantLock、ReentrantReadWriteLock、CountDownLatch 和 Semaphore。

(1)AQS 核心概念

AQS 中有兩個最主要的內容:

  • 同步狀態(State):用于表示同步器的狀態,例如鎖的持有數量、資源的可用數量等。可以通過 getState()、setState() 和 compareAndSetState() 方法來操作。
  • 等待隊列(CLH 隊列):由雙向鏈表實現的等待線程隊列。當線程獲取同步狀態失敗時,會被封裝成節點加入到等待隊列中。

(2)AQS 工作流程

AQS 工作流程主要分為以下兩部分。

加鎖與釋放鎖:

  • 線程嘗試獲取同步狀態,如果獲取成功,則直接執行后續操作。
  • 如果獲取失敗,則將當前線程封裝成節點加入等待隊列,并阻塞當前線程。
  • 當持有鎖的線程釋放鎖時,會喚醒等待隊列中的后繼節點線程,使其重新嘗試獲取鎖。

等待與喚醒:

  • 等待隊列中的節點通過自旋和阻塞來等待被喚醒。
  • 喚醒操作會按照一定的規則選擇等待隊列中的節點進行喚醒。
責任編輯:姜華 來源: 磊哥和Java
相關推薦

2024-03-05 10:33:39

AOPSpring編程

2024-08-22 10:39:50

@Async注解代理

2024-02-29 16:49:20

volatileJava并發編程

2024-08-29 16:30:27

2024-03-28 10:37:44

IoC依賴注入依賴查找

2024-07-31 08:28:37

DMAIOMMap

2024-03-14 14:56:22

反射Java數據庫連接

2024-12-06 07:00:00

2021-05-20 08:34:03

CDN原理網絡

2024-03-22 06:56:24

零拷貝技術數據傳輸數據拷貝

2024-09-20 08:36:43

零拷貝數據傳輸DMA

2024-06-04 09:02:03

2024-11-15 15:27:09

2025-02-28 00:00:00

2021-06-07 17:12:22

線程安全Atomic

2025-04-07 00:00:00

MySQL數據庫服務器

2024-03-01 11:33:31

2024-12-04 14:45:14

零拷貝技術CPU 拷貝Zero-copy

2024-11-19 15:13:02

2023-12-27 18:16:39

MVCC隔離級別幻讀
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品不卡 | 国产真实精品久久二三区 | 激情小说综合网 | 日韩一区二区在线视频 | 精品国产一区二区在线 | 欧美日韩在线精品 | 中文字幕在线观看视频一区 | 精品国产乱码久久久久久影片 | 精品91久久 | 精品国产一区二区三区av片 | 日本三级做a全过程在线观看 | 日韩中文字幕在线不卡 | 中文字幕三区 | 国产日韩欧美激情 | 亚洲欧美日韩一区 | 国产在线a | 激情网站 | 91九色porny首页最多播放 | 亚洲成人一区二区 | xx视频在线观看 | 久久综合国产精品 | 久久蜜桃资源一区二区老牛 | 成人午夜精品一区二区三区 | 中文字幕不卡在线88 | 国产精品美女久久久免费 | 亚洲午夜精品 | 国产国拍亚洲精品av | 少妇久久久久 | 中文字幕av网站 | 亚洲成人自拍 | 国产精品美女久久久久aⅴ国产馆 | 欧美午夜精品久久久久免费视 | 久久精品国产99国产精品 | 久草视频观看 | 最新av在线播放 | 国产成人精品免高潮在线观看 | 91免费在线视频 | 久久久久国产一区二区三区 | 亚洲精品一| 婷婷色在线 | 欧美在线综合 |