java多线程(十六)读写锁

基于白嫖B站黑马程序员视频:全面深入学习java并发编程,java基础进阶中级必会教程

1 ReentrantReadWriteLock

支持可重入的读写锁,在于优化读写,读时间远远小于写,所以希望读-读并发。

1.1 使用例子

class Data {
    private String data;//数据
    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();//读写锁
    private ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();//获取读锁
    private ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();//获取写锁

    //读方法
    public String read() {
        readLock.lock();
        try {
            return this.data;
        } finally {
            readLock.unlock();
        }
    }

    //写方法
    public void write(String s) {
        writeLock.lock();
        try {
            this.data = s;
        } finally {
            writeLock.unlock();
        }
    }
}

测试容易发现:读-读并发,读-写(写-读)互斥,写-写互斥;

1.2 注意点

  • 读锁不支持条件变量condition;
  • 重入不支持升级,即先获取读锁,想要获取写锁,不允许,会导致写锁永久等待;
  • 重入支持降级,即先获得写锁,允许再获得读锁;

1.3 原理

  • 使用的是同一个AQS同步器;
  • 写锁占state低16位,读锁占state高16位;
  • 一系列的读写逻辑;

2 StampedLock

jdk8加入的一种锁,优化读性能,要配合戳来使用;

StampedLock stampedLock = new StampedLock();//得到锁

long stamp = stampedLock.readLock();//获得读锁
stampedLock.unlockRead(stamp);//释放读锁

long stamp = stampedLock.writeLock();//获得写锁
stampedLock.unlockWrite(stamp);//释放写锁

注意新加内容:乐观读

stampedLock.tryOptimisticRead();//乐观读

主要用于优化读,加了戳校验,直接获取值,没有CAS操作,要是发现读之前和读之后,戳没有变,说明没有对值进行更改,可以使用,要是发生了更改,就锁升级,去读;

  • 不支持条件变量;
  • 不支部可重入;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值