Java—多线程8 ReentranReadWriteLock可重入读写锁

Java—多线程8 ReentranReadWriteLock可重入读写锁

读写者模型

读写锁允许同一时刻被多个读线程访问,但在写线程访问时,所有的读线程以及其他写线程均会被阻塞。

写锁是一个独占锁:

读锁!= 无锁:

如果 读锁==无锁,当有写线程时,读线程不会停止。

如果 读锁!=写锁 当有写线程访问时,读线程会被停止

写锁—独占锁

1.写锁的获取:

 protected final boolean tryAcquire(int acquires) {
            /*
             * Walkthrough:
             * 1. If read count nonzero or write count nonzero
             *    and owner is a different thread, fail.
           
             * 2. If count would saturate, fail. (This can only
             *    happen if count is already nonzero.)
           
             * 3. Otherwise, this thread is eligible for lock if
             *    it is either a reentrant acquire or
             *    queue policy allows it. If so, update state
             *    and set owner.
             
             
     
             
             
     		当前的读写锁没有被任何读线程获取并且写锁要么是0,要么被你自己获取        
             
             
             
             */
            Thread current = Thread.currentThread();
     		//获取读写锁状态
            int c = getState();
     		//获取独占式锁状态,即写锁状态
            int w = exclusiveCount(c);
     		
            if (c != 0) {
             // 表示当前有读线程拿到读锁,写线程无法拿到同步状态
                if (w == 0 || current != getExclusiveOwnerThread())
                    return false;
               //表示写锁可重入次数已经到达上限
                if (w + exclusiveCount(acquires) > MAX_COUNT)
                    throw new Error("Maximum lock count exceeded");
                // 写锁可重入
                setState(c + acquires);
                return true;
            }
     		
            if (writerShouldBlock() ||
                !compareAndSetState(c, c + acquires))
                return false;
    		 //此时读写状态为0,写锁可以正常获取到同步状态
     		//当前线程置为写锁线程
            setExclusiveOwnerThread(current);
            return true;
        }

如何区分读状态和写状态

同步状态的高16位标书读锁的次数;同步状态的低16位表示写锁的次数

2.写锁的释放

 protected final boolean tryRelease(int releases) {
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
     		//同步状态减去写锁状态
            int nextc = getState() - releases;
     		//当前写锁状态是否为0,为0则释放写锁
            boolean free = exclusiveCount(nextc) == 0;
            if (free)
                setExclusiveOwnerThread(null);
     		//不为0则更新同步状态
            setState(nextc);
            return free;
        }

读锁—共享锁(一般与独占锁搭配使用实现读写者模型)

获取:只要当前没有写线程获取到写锁,并且读锁的获取次数不超过最大值,读锁就可以获取成功。

释放:自旋,将同步状态减去读状态即可,如果减到0,就可以释放锁

应用场景:所有缓存的实现必有读写锁,缓存一定是个共享资源,

写锁的降级

写锁可以降级成写锁,写锁不能降级成读锁。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值