并发编程-读写锁ReentrantReadWriteLock详解 & StampLock详解

现实中有这样一种场景对共享资源有读和写的操作,且写操作没有读操作那么频繁(读多写少)

在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源(读读共享);但是如果一个线程想去写这些共享资源,就不应该允许其他线程对该资源进行读和写操作了(读写,写写互斥)。

思考:针对这种场景,有没有比ReentrantLock更好的方案?

在这里插入图片描述

1. 读写锁介绍

读写锁ReadWriteLock,顾名思义一把锁分为读与写两部分,读锁允许多个线程同时获得,因为读操
作本身是线程安全的。而写锁是互斥锁,不允许多个线程同时获得写锁。并且读与写操作也是互斥
的。读写锁适合多读少写的业务场景。

2. ReentrantReadWriteLock介绍

针对这种场景,JAVA的并发包提供了读写锁ReentrantReadWriteLock,它内部,维护了一对相关的锁,一个用于只读操作,称为读锁;一个用于写入操作,称为写锁,描述如下:
线程进入读锁的前提条件:
1.没有其他线程的写锁
2.没有写请求或者有写请求,但调用线程和持有锁的线程是同一个。

线程进入写锁的前提条件:
1.没有其他线程的读锁
2.没有其他线程的写锁

而读写锁有以下三个重要的特性:
公平选择性:支持非公平(默认)和公平的锁获取方式,吞吐量还是非公平优于公平。
可重入:读锁和写锁都支持线程重入。以读写线程为例:读线程获取读锁后,能够再次获取读锁。写线程在获取写锁之后能够再次获取写锁,同时也可以获取读锁。
锁降级遵循获取写锁、再获取读锁最后释放写锁的次序,写锁能够降级成为读锁。

2.1 ReentrantReadWriteLock的使用

读写锁接口ReadWriteLock

一对方法,分别获得读锁和写锁 Lock 对象。

ReentrantReadWriteLock类结构

ReentrantReadWriteLock是可重入的读写锁实现类。在它内部,维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有 Writer 线程,读锁可以由多个 Reader 线程同时持有。也就是说,写锁是独占的,读锁是共享的。

如何使用读写锁

public class ReadWriteLockExample {
   
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final Lock readLock = lock.readLock();//读锁
    private final Lock writeLock = lock.writeLock();//写锁
    private final String[] data = new String[10];

    public void write(int index, String value) {
   
        writeLock.lock();
        try {
   
            System.out.println(Thread.currentThread().getName()+"获取写锁");
            try {
   
                Thread.sleep(5000);
            } catch (InterruptedException e) {
   
                throw new RuntimeException(e);
            }
          //  read(2);
            data[index] = value;
        } finally {
   
            System.out.println(Thread.currentThread().getName()+"释放写锁");
            writeLock.unlock();
        }
    }

    public String read(int index) {
   
        readLock.lock();
        try {
   
            System.out.println(Thread.currentThread().getName()+"获取读锁");
            try {
   
                Thread.sleep(3000);
            } catch (InterruptedException e) {
   
                throw new RuntimeException(e);
            }
            return data[index];
        } finally {
   
            System.out.println(Thread.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长情知热爱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值