首頁 >Java >java教程 >Java讀寫鎖的用法及其優點是什麼?

Java讀寫鎖的用法及其優點是什麼?

WBOY
WBOY轉載
2023-04-20 15:25:08880瀏覽
前言:

讀寫鎖(Readers-Writer Lock)顧名思義是一把鎖分為兩部分:讀鎖和寫鎖,其中讀鎖允許多個執行緒同時取得,因為讀取操作本身是執行緒安全的,而寫鎖則是互斥鎖,不允許多個執行緒同時取得寫鎖,且寫入操作和讀取操作也是互斥的。總結來說,讀寫鎖的特徵是:讀讀不互斥、讀寫互斥、寫寫互斥

1.讀寫鎖定使用

在Java 語言中,讀寫鎖定是使用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.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();

以上程式執行結果如下: 

Java讀寫鎖的用法及其優點是什麼?

#1.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();

以上程式執行結果如下: 

Java讀寫鎖的用法及其優點是什麼?

1.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();

以上程式執行結果如下: 

Java讀寫鎖的用法及其優點是什麼?

2.優點分析

  • 提升了程式執行效能:多個讀鎖可以同時執行,相較於普通鎖在任何情況下都要排隊執行來說,讀寫鎖提高了程式的執行效能。

  • 避免讀到臨時資料:讀取鎖定和寫入鎖定是互斥排隊執行的,這樣可以保證了讀取操作不會讀到寫了一半的臨時數據。

3.適用場景

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

以上是Java讀寫鎖的用法及其優點是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除