ReentrantReadWriteLock是什么呢?
下文笔者讲述ReentrantReadWriteLock简介说明,如下所示
在多线程环境中使用读锁和写锁来管理共享资源
ReentrantReadWriteLock简介
`ReentrantReadWriteLock` 是 Java 并发包(`java.util.concurrent.locks`)中的一个类,
用于提供读写锁的实现
ReentrantReadWriteLock锁允许多个线程同时读取共享资源
但在写入时只允许一个线程进行写操作。
使用此种锁机制可以显著提高并发性能,特别是在读操作远多于写操作的场景中
ReentrantReadWriteLock主要特点
1.读写分离:
-读锁(Read Lock):
允许多个线程同时持有读锁,
进行读操作。
-写锁(Write Lock):
只允许一个线程持有写锁,进行写操作。
当写锁被某个线程持有时,
其他线程(无论是读线程还是写线程)都必须等待,
直到写锁被释放。
2.可重入性:
-读锁:支持可重入读锁,
即同一个线程可以多次获取读锁。
-写锁:支持可重入写锁,
即同一个线程可以多次获取写锁。
3.公平性选择:
- 可以选择是否使用公平锁。
公平锁会按照线程请求锁的顺序来分配锁,
而非公平锁则允许插队。
4.锁降级:
- 支持锁降级,即一个线程可以先获取写锁,
然后获取读锁,最后释放写锁。
这有助于避免死锁。
ReentrantReadWriteLock使用场景
-读多写少:
适用于读操作远多于写操作的场景,
如缓存系统、配置文件读取等。
-数据一致性:
需要保证数据一致性的场景,
如数据库连接池、共享资源管理等。
-性能优化:
通过允许多个读线程同时访问,
提高并发性能。
示例代码
使用`ReentrantReadWriteLock`在多线程环境中使用读锁和写锁来管理共享资源
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class SharedResource {
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private final ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
private final ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();
private String data;
// 读取数据
public String readData() {
readLock.lock();
try {
// 模拟读取操作
System.out.println(Thread.currentThread().getName() + " is reading data: " + data);
return data;
} finally {
readLock.unlock();
}
}
// 写入数据
public void writeData(String newData) {
writeLock.lock();
try {
// 模拟写入操作
System.out.println(Thread.currentThread().getName() + " is writing data: " + newData);
data = newData;
} finally {
writeLock.unlock();
}
}
public static void main(String[] args) {
SharedResource resource = new SharedResource();
// 写线程
Thread writerThread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
resource.writeData("Data " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "WriterThread");
// 读线程
Thread readerThread1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
resource.readData();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "ReaderThread1");
Thread readerThread2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
resource.readData();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "ReaderThread2");
writerThread.start();
readerThread1.start();
readerThread2.start();
}
}
代码详解
1.定义`ReentrantReadWriteLock`和锁:
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private final ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
private final ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();
private String data;
- `rwLock`:创建一个 `ReentrantReadWriteLock` 实例。
- `readLock`:获取读锁。
- `writeLock`:获取写锁。
- `data`:共享资源,可以是任何数据结构。
2.读取数据:
public String readData() {
readLock.lock();
try {
// 模拟读取操作
System.out.println(Thread.currentThread().getName() + " is reading data: " + data);
return data;
} finally {
readLock.unlock();
}
}
- `readLock.lock()`:获取读锁。
- `try` 块:执行读操作。
- `finally` 块:确保读锁在任何情况下都能被释放。
3.写入数据:
public void writeData(String newData) {
writeLock.lock();
try {
// 模拟写入操作
System.out.println(Thread.currentThread().getName() + " is writing data: " + newData);
data = newData;
} finally {
writeLock.unlock();
}
}
- `writeLock.lock()`:获取写锁。
- `try` 块:执行写操作。
- `finally` 块:确保写锁在任何情况下都能被释放。
4.主方法:
public static void main(String[] args) {
SharedResource resource = new SharedResource();
// 写线程
Thread writerThread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
resource.writeData("Data " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "WriterThread");
// 读线程
Thread readerThread1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
resource.readData();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "ReaderThread1");
Thread readerThread2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
resource.readData();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "ReaderThread2");
writerThread.start();
readerThread1.start();
readerThread2.start();
}
-写线程:每隔1秒写入一次数据。
-读线程:每隔0.5秒读取一次数据。
运行以上代码,将输出以下信息 WriterThread is writing data: Data 0 ReaderThread1 is reading data: Data 0 ReaderThread2 is reading data: Data 0 ReaderThread1 is reading data: Data 0 ReaderThread2 is reading data: Data 0 WriterThread is writing data: Data 1 ReaderThread1 is reading data: Data 1 ReaderThread2 is reading data: Data 1 ReaderThread1 is reading data: Data 1 ReaderThread2 is reading data: Data 1 WriterThread is writing data: Data 2 ReaderThread1 is reading data: Data 2 ReaderThread2 is reading data: Data 2 ReaderThread1 is reading data: Data 2 ReaderThread2 is reading data: Data 2 WriterThread is writing data: Data 3 ReaderThread1 is reading data: Data 3 ReaderThread2 is reading data: Data 3 ReaderThread1 is reading data: Data 3 ReaderThread2 is reading data: Data 3 WriterThread is writing data: Data 4 ReaderThread1 is reading data: Data 4 ReaderThread2 is reading data: Data 4 ReaderThread1 is reading data: Data 4 ReaderThread2 is reading data: Data 4
ReentrantReadWriteLock关键点总结
1.读写分离:
- 多个读线程可以同时读取数据。
- 只有一个写线程可以写入数据,
其他读线程和写线程必须等待。
2.可重入性:
- 同一个线程可以多次获取读锁或写锁。
- 写锁可以降级为读锁,但读锁不能升级为写锁。
3.公平性选择:
- 可以选择公平锁或非公平锁。
- 公平锁会按照线程请求锁的顺序分配锁,
而非公平锁允许插队。
4.锁降级:
- 支持锁降级,即先获取写锁,
然后获取读锁,最后释放写锁。
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


