ReentrantReadWriteLock

ReentrantReadWriteLock包含了两个锁,一个是读操作相关的锁,称为共享锁;一个是写相关的锁,称为独占锁;

  • 线程进入读锁的前提条件:

没有其他线程的写锁,

没有写请求或者有写请求,但调用线程和持有锁的线程是同一个。

  • 线程进入写锁的前提条件:

没有其他线程的读锁

没有其他线程的写锁

  • 而读写锁有以下三个重要的特性:

(1)公平选择性:支持非公平(默认)和公平的锁获取方式,吞吐量还是非公平优于公平。

(2)重入:读锁和写锁都支持线程重进入。

(3)锁降级:遵循获取写锁、获取读锁再释放写锁的次序,写锁能够降级成为读锁。

ReentrantLock是一个排他锁,同一时间只允许一个线程访问,而ReentrantReadWriteLock允许多个读线程同时访问,但不允许写线程和读线程、写线程和写线程同时访问。相对于排他锁,提高了并发性。在实际应用中,大部分情况下对共享数据(如缓存)的访问都是读操作远多于写操作,这时ReentrantReadWriteLock能够提供比排他锁更好的并发性和吞吐量。

读写锁将AQS中的state整型做了一下处理,它是一个int型变量一共4个字节32位,那么可以读写状态就可以各占16位——高16位表示读,低16位表示写。

  • 用法:
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();// 读写锁

读读共享

public String readI() {
        try {
            lock.readLock().lock();// 占用读锁
            log.info("threadName -> {} 占用读锁,i->{}", Thread.currentThread().getName(), i);
            Thread.sleep(2 * 1000);
        } catch (InterruptedException e) {

        } finally {
            log.info("threadName -> {} 释放读锁,i->{}", Thread.currentThread().getName(), i);
            lock.readLock().unlock();// 释放读锁
        }
        return i + "";
    }

写写互斥

public void addI() {
        try {
            lock.writeLock().lock();// 占用写锁
            log.info("threadName -> {} 占用写锁,i->{}", Thread.currentThread().getName(), i);
            Thread.sleep(2 * 1000);
            i++;
        } catch (InterruptedException e) {

        } finally {
            log.info("threadName -> {} 释放写锁,i->{}", Thread.currentThread().getName(), i);
            lock.writeLock().unlock();// 释放写锁
        }
    }

读写互斥

public String readI() {
        try {
            lock.readLock().lock();// 占用读锁
            log.info("threadName -> {} 占用读锁,i->{}", Thread.currentThread().getName(), i);
            Thread.sleep(2 * 1000);
        } catch (InterruptedException e) {

        } finally {
            log.info("threadName -> {} 释放读锁,i->{}", Thread.currentThread().getName(), i);
            lock.readLock().unlock();// 释放读锁
        }
        return i + "";
    }

    public void addI() {
        try {
            lock.writeLock().lock();// 占用写锁
            log.info("threadName -> {} 占用写锁,i->{}", Thread.currentThread().getName(), i);
            Thread.sleep(2 * 1000);
            i++;
        } catch (InterruptedException e) {

        } finally {
            log.info("threadName -> {} 释放写锁,i->{}", Thread.currentThread().getName(), i);
            lock.writeLock().unlock();// 释放写锁
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值