ReentrantReadWriteLock是什么呢?

欣喜 Java经验 发布时间:2025-03-21 11:37:01 阅读数:822 1
下文笔者讲述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.锁降级:
   - 支持锁降级,即先获取写锁,
   然后获取读锁,最后释放写锁。
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaJingYan/202503/17425282488386.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者