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.锁降级: - 支持锁降级,即先获取写锁, 然后获取读锁,最后释放写锁。
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。