你了解 Java 中的读写锁吗?

Sherwin.Wei Lv7

你了解 Java 中的读写锁吗?

回答重点

读写锁,它允许多个线程同时读取共享资源,而在写操作时确保只有一个线程能够进行写操作(读读操作不互斥,读写互斥、写写互斥)。这种机制适合于读多写少的场景,因为它提高了系统的并发性和性能。

Java 中的 ReadWriteLock 是通过 ReentrantReadWriteLock 实现的,它提供了以下两种锁模式:

  • 读锁(共享锁):允许多个线程同时获取读锁,只要没有任何线程持有写锁。适合读操作频繁而写操作较少的场景。
  • 写锁(独占锁):写锁是独占的,当有线程持有写锁时,其他线程既不能获取写锁,也不能获取读锁。写锁用于保证写操作的独占性,防止数据不一致。

扩展知识

读写锁的原理

  • 共享与独占:读锁是共享锁,多个线程可以同时获取;而写锁是独占锁,在持有写锁期间,其他线程不能获取写锁或读锁。
  • 锁降级ReentrantReadWriteLock 支持锁降级,即持有写锁的线程可以直接获取读锁,从而在写操作完成后不必完全释放锁,但不支持锁升级(即不能从读锁升级为写锁)。
  • 公平锁与非公平锁ReentrantReadWriteLock 提供了公平和非公平模式。在公平模式下,线程将按照请求的顺序获取锁;而在非公平模式下,线程可能会插队,提高吞吐量。
  • 读写锁也是基于 AQS 实现的,再具体点的实现就是将 state 分为了两部分,高16bit用于标识读状态、低16bit标识写状态。

AQS

ReentrantReadWriteLock 的使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ReadWriteLock lock = new ReentrantReadWriteLock();
Lock readLock = lock.readLock();
Lock writeLock = lock.writeLock();

// 读操作
readLock.lock();
try {
// 读取共享资源
} finally {
readLock.unlock();
}

// 写操作
writeLock.lock();
try {
// 修改共享资源
} finally {
writeLock.unlock();
}
Comments