java-锁-StampedLock

对于"StampedLock"提供了三种锁模式

  • 读锁-互斥
  • 写锁-共享
  • 优势读锁

对于读锁和优势读锁的区别在于,对于读锁是利用cas操作变更状态,但存在一定的几率出现读等待的情况,而对于优势读操作,只需要简单的位运算操作,如果在排他锁持有情况下,这直接返回0,反之则返回非0版本号数据;

相对而言优势读的性能消耗更小;

在api中提供了丰富的锁校验;

对于"StampedLock"提供了锁升级(转换)和锁降级

  • 对于锁降级要求必须在互斥锁释放情况下才能执行,但如果当前锁未共享锁,则可以直接执行; 但要求所有的锁都必须存在unlock
  • 对于锁转换(升级),其重点含义在于转换,当锁转换后转换前的锁已不存在,只需要释放转换后的锁

对于优势读锁不需要手动释放锁

 

public static void main(String[] args) {
        StampedLock stampedLock = new StampedLock();
        long writeLockStamp = stampedLock.writeLock();
//        long l = stampedLock.tryOptimisticRead();
        // 转换为读锁,对于写锁本身时互斥锁,并不能自动降级,因此可以使用api主动转换锁类型
        long l = stampedLock.tryConvertToOptimisticRead(writeLockStamp);
        boolean validate = stampedLock.validate(l);
        log.info("是否为读锁:{}", StampedLock.isReadLockStamp(l));
        if (validate) {
            // 当锁进行人工转换时,则原来的锁已经不存在
            log.info("获取到优势读锁");
        } else {
            log.info("未获取到优势读锁");
            stampedLock.unlockWrite(writeLockStamp);
        }

        long readLockStamp = stampedLock.readLock();
        if (stampedLock.validate(readLockStamp)) {
            log.info("执行读锁加锁成功");
            l = stampedLock.tryOptimisticRead();
            if (stampedLock.validate(l)) {
                // 对于优势读锁不需要主动释放锁
                log.info("转换为优势读锁成功");
//                long writeLock = stampedLock.writeLock(); // 当前代码会被阻塞
stampedLock.tryConvertToReadLock(l);
log.info("写锁加锁成功");
            }
            stampedLock.unlockRead(readLockStamp);
        }
    }

 对于StampedLock适合的场景为读多写少的情况,且和ReentrantWriteAndReadLock中的readLock对比,由于存在优势读的存在,以及更加自由的锁升级情况;

posted @ 2020-09-27 14:55  郭星  阅读(247)  评论(0)    收藏  举报