ReentrantReadWriteLock之 WriteLock源码

与读锁加锁的过程类似,写锁的加锁过程分为如下几步:

public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

首先我们先进入tryAcquire方法中(本文仍是以非公平锁为例)

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.
             */
            Thread current = Thread.currentThread();
            int c = getState();
            //获取持有写锁数量
            int w = exclusiveCount(c);
            //因为读写互斥、写写互斥,所以c!=0表示有别的线程持有锁
            if (c != 0) {
                // (Note: if c != 0 and w == 0 then shared count != 0)
                //如果持有锁的线程不是当前线程,即表明不是写锁重入的情况下,直接return false
                if (w == 0 || current != getExclusiveOwnerThread())
                    return false;
                if (w + exclusiveCount(acquires) > MAX_COUNT)
                    throw new Error("Maximum lock count exceeded");
                // Reentrant acquire
                //写锁重入,无需CAS,无法做到CAS并发
                setState(c + acquires);
                return true;
            }
            //writerShouldBlock()永远返回false,因为偏向锁概念即写锁优先
            //CAS加锁失败false
            if (writerShouldBlock() ||
                !compareAndSetState(c, c + acquires))
                return false;
            //成功将该所置为独占锁的持有者
            setExclusiveOwnerThread(current);
            return true;
        }

如果枷锁失败的话需要尝试将该线程加入到QAS队列中,其方法为addWaiter,这部分过程与ReentrantLock一样。这里不做多介绍。

写锁释放
对于释放过程,其过程如下所示:

public final boolean release(int arg) {
		//tryRelease已经全部释放掉了
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);//唤醒后续线程
            return true;
        }
        return false;
    }

首先我们进入tryRelease过程

 protected final boolean tryRelease(int releases) {
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            //低16为表示写锁的持有数量
            int nextc = getState() - releases;
            //该线程所重入的线程已经全部释放了
            boolean free = exclusiveCount(nextc) == 0;
            if (free)
                setExclusiveOwnerThread(null);
            setState(nextc);
            return free;
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值