java源码 - ReentrantReadWriteLock写锁介绍

简介: 开篇 这篇文章主要从源码角度讲解ReentrantReadWriteLock的WriteLock的加锁和减锁过程。 ReentrantReadWriteLock的WriteLock加锁解锁过程依赖于AbstractQueuedSynchronizer(AQS)类,所以有些相同的逻辑可以看看ReentrantLock的逻辑。

开篇

 这篇文章主要从源码角度讲解ReentrantReadWriteLock的WriteLock的加锁和减锁过程。
 ReentrantReadWriteLock的WriteLock加锁解锁过程依赖于AbstractQueuedSynchronizer(AQS)类,所以有些相同的逻辑可以看看ReentrantLock的逻辑。


加锁过程

  • WriteLock的lock()内部通过sync.acquire(1)获取锁。
  • 尝试通过tryAcquire获取写锁,如果获取成功那么就成功占用写锁。
  • 获取写锁失败后,将当前线程添加到写锁唤醒队列当中acquireQueued(addWaiter(Node.EXCLUSIVE), arg))。
  • acquireQueued(addWaiter(Node.EXCLUSIVE), arg))的操作逻辑和ReentrantLock的逻辑一致。
    public static class WriteLock implements Lock, java.io.Serializable {
        private static final long serialVersionUID = -4992448646407690164L;
        private final Sync sync;

        protected WriteLock(ReentrantReadWriteLock lock) {
            sync = lock.sync;
        }

        public void lock() {
            sync.acquire(1);
        }
    }

    public final void acquire(int arg) {
        // 1、先尝试获取锁tryAcquire
        // 2、获锁失败就addWaiter操作
        // 3、acquireQueued判断是否唤醒
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

tryAcquire过程

  • 获取锁状态state变量,并获取写锁占用的计数值。
  • 当前state不为0,如果写锁状态为0说明读锁被占用,返回锁占用失败。
  • 锁状态state不为空且占锁线程为当前线程,说明锁被其他线程占用返回锁占用失败。
  • 写锁重入数溢出,返回锁占用失败。
  • 如果写锁阻塞 或者 设置state状态失败,返回锁占用失败。
  • 设置当前锁占用线程为当前线程,返回锁占用成功。
    protected final boolean tryAcquire(int acquires) {
            Thread current = Thread.currentThread();
            // 获取锁状态state变量
            int c = getState();
            // 获取写锁占用的计数
            int w = exclusiveCount(c);
            // 如果锁状态state不为0
            if (c != 0) {
                // 1、当前state不为0,如果写锁状态为0说明读锁此时被占用,说明锁被读锁占用
                // 2、锁状态state不为空且占锁线程为当前线程(属于锁重入),说明锁被其他线程占用
                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;
            }
            // 如果写锁阻塞 或者 设置state状态失败,那么就代表获锁失败
            if (writerShouldBlock() ||
                !compareAndSetState(c, c + acquires))
                return false;
            // 设置当前锁占用线程为当前线程
            setExclusiveOwnerThread(current);
            return true;
        }


解锁过程

  • WriteLock的unlock()内部通过sync. release(1)释放锁。
  • 尝试通过tryRelease()方法来释放锁并唤醒下一个等待线程。
  • 在唤醒过程中需要仔细看看读写锁等待线程唤醒的细节,待补充
    public void unlock() {
        sync.release(1);
    }

    public final boolean release(int arg) {
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }

tryRelease过程

  • 判断当前线程和锁占用线程不一致isHeldExclusively()抛出异常。
  • 锁状态减去当前释放动作传入参数nextc = getState() - releases。
  • 判断锁状态的写状态为0就表明当前线程已经完全释放锁。
  • 当前线程完全释放锁,然后设置锁占用线程为null并设置锁状态。
    protected final boolean tryRelease(int releases) {
        if (!isHeldExclusively())
            throw new IllegalMonitorStateException();
        int nextc = getState() - releases;
        boolean free = exclusiveCount(nextc) == 0;
        if (free)
            setExclusiveOwnerThread(null);
        setState(nextc);
        return free;
    }
目录
相关文章
|
1天前
|
JavaScript Java 测试技术
基于Java的快递信息管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的快递信息管理系统的设计与实现(源码+lw+部署文档+讲解等)
28 5
|
1天前
|
JavaScript Java 测试技术
基于Java的通讯录管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的通讯录管理系统的设计与实现(源码+lw+部署文档+讲解等)
26 5
|
1天前
|
JavaScript Java 测试技术
基于Java的普通话培训信息管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的普通话培训信息管理系统的设计与实现(源码+lw+部署文档+讲解等)
32 9
|
1天前
|
JavaScript Java 测试技术
基于Java的在线开放课程的设计与实现(源码+lw+部署文档+讲解等)
基于Java的在线开放课程的设计与实现(源码+lw+部署文档+讲解等)
30 3
|
1天前
|
JavaScript Java 测试技术
基于Java的个人消费管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的个人消费管理系统的设计与实现(源码+lw+部署文档+讲解等)
26 4
|
1天前
|
JavaScript Java 测试技术
基于Java的大学生校园招聘网的设计与实现(源码+lw+部署文档+讲解等)
基于Java的大学生校园招聘网的设计与实现(源码+lw+部署文档+讲解等)
22 3
|
1天前
|
JavaScript Java 测试技术
基于Java的社区人员管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的社区人员管理系统的设计与实现(源码+lw+部署文档+讲解等)
18 2
|
1天前
|
JavaScript Java 测试技术
基于Java的学生就业管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的学生就业管理系统的设计与实现(源码+lw+部署文档+讲解等)
20 3
|
1天前
|
JavaScript Java 测试技术
基于Java的公司员工工作日志办公系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的公司员工工作日志办公系统的设计与实现(源码+lw+部署文档+讲解等)
23 3
|
1天前
|
JavaScript Java 测试技术
基于Java的图书馆智能选座系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的图书馆智能选座系统的设计与实现(源码+lw+部署文档+讲解等)
16 2