ReentrantReadWriteLock读写锁源码学习

ReentrantReadWriteLock锁的属性如下

 	// 这里持有了读锁
    private final ReentrantReadWriteLock.ReadLock readerLock;
    // 这里持有了写锁
    private final ReentrantReadWriteLock.WriteLock writerLock;
    // 内部同步类
    final Sync sync;

ReentrantReadWriteLock的构造函数如下

	public ReentrantReadWriteLock() {
		// 默认是非公平方式创建锁
        this(false);
    }
    // 可以看到这里创建了读锁和写锁
    public ReentrantReadWriteLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
        readerLock = new ReadLock(this);
        writerLock = new WriteLock(this);
    }
    // 这是读锁的构造函数
    protected ReadLock(ReentrantReadWriteLock lock) {
        sync = lock.sync;
    }
    // 这是写锁的构造函数
    protected WriteLock(ReentrantReadWriteLock lock) {
        sync = lock.sync;
    }

重点看下静态内部类Sync

		static final int SHARED_SHIFT   = 16;
        static final int SHARED_UNIT    = (1 << SHARED_SHIFT);
        static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;
        static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
        // int变量高16位表示读状态
        static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }
        // int变量低16位表示写状态
        static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
		// 构造函数
        Sync() {
            readHolds = new ThreadLocalHoldCounter();
            setState(getState()); // ensures visibility of readHolds
        }

readerShouldBlock方法

	abstract boolean readerShouldBlock();
	
	// 这个方法有两个实现分别是FairSync中
	static final class FairSync extends Sync {
        private static final long serialVersionUID = -2274990926593161451L;
        final boolean writerShouldBlock() {
            return hasQueuedPredecessors();
        }
        final boolean readerShouldBlock() {
        	// 判断当前节点是否有前驱节点
            return hasQueuedPredecessors();
        }
    }
    // 和NonfairSync中
	static final class NonfairSync extends Sync {
        private static final long serialVersionUID = -8159625535654395037L;
        final boolean writerShouldBlock() {
            return false; // writers can always barge
        }
        final boolean readerShouldBlock() {
            return apparentlyFirstQueuedIsExclusive();
        }
    }

看看tryAcquire方法实现

		protected final boolean tryAcquire(int acquires) {        
            Thread current = Thread.currentThread();
            int c = getState();
            // 获取写锁的状态
            int w = exclusiveCount(c);
            if (c != 0) {
                // (Note: if c != 0 and w == 0 then shared count != 0)
                // 读锁有获取,写锁获取失败
                if (w == 0 || current != getExclusiveOwnerThread())
                    return false;
                if (w + exclusiveCount(acquires) > MAX_COUNT)
                    throw new Error("Maximum lock count exceeded");
                // Reentrant acquire
                // 重入获取写锁
                setState(c + acquires);
                return true;
            }
            if (writerShouldBlock() ||
                !compareAndSetState(c, c + acquires))
                return false;
            // 设置排他锁拥有者线程为当前线程
            setExclusiveOwnerThread(current);
            return true;
        }

看看tryRelease方法实现

		protected final boolean tryRelease(int releases) {
			// 如果当前线程不是独占的那个线程,状态不对抛异常
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            int nextc = getState() - releases;
            // 判断写锁是否是否完成资源,释放完成free为true
            boolean free = exclusiveCount(nextc) == 0;
            if (free)
            	// 释放完成,置空
                setExclusiveOwnerThread(null);
            // 无需加锁,其他线程进不来
            setState(nextc);
            // 如果没有释放完返回false
            return free;
        }

看看读锁的获取

		protected final int tryAcquireShared(int unused) {
            
            Thread current = Thread.currentThread();
            int c = getState();
            // 写锁获取了并且独占式的线程不是当前线程,获取资源失败
            if (exclusiveCount(c) != 0 &&
                getExclusiveOwnerThread() != current)
                // 失败
                return -1;
            int r = sharedCount(c);
            if (!readerShouldBlock() &&
                r < MAX_COUNT &&
                compareAndSetState(c, c + SHARED_UNIT)) {
                // 如果读锁状态为0
                if (r == 0) {
                    firstReader = current;
                    firstReaderHoldCount = 1;
                } else if (firstReader == current) {
                    firstReaderHoldCount++;
                } else {
                    HoldCounter rh = cachedHoldCounter;
                    if (rh == null || rh.tid != getThreadId(current))
                        cachedHoldCounter = rh = readHolds.get();
                    else if (rh.count == 0)
                        readHolds.set(rh);
                    rh.count++;
                }
                return 1;
            }
            return fullTryAcquireShared(current);
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值