AQS之ReentrantReadWriteLock写锁 (2)

ReentrantReadWriteLock中tryRelease方法

protected final boolean tryRelease(int releases) { // 若锁的持有者不是当前线程,抛出异常 if (!isHeldExclusively()) // 非法的监控器异常 throw new IllegalMonitorStateException(); // 计算写锁的新线程数 int nextc = getState() - releases; // 如果独占模式重入数为0了,说明独占模式被释放 boolean free = exclusiveCount(nextc) == 0; if (free) // 设置独占线程为空 setExclusiveOwnerThread(null); // 设置写锁的新线程数 // 不管独占模式是否被释放,更新独占重入数 setState(nextc); return free; } protected final boolean isHeldExclusively() { // 若当前线程是当前锁的持有线程那么返回true return getExclusiveOwnerThread() == Thread.currentThread(); }

释放写锁流程图

5.1 流程图释放过程

在这里插入图片描述

5.2 流程图释放过程解析

写锁的释放过程:

首先查看当前线程是否为写锁的持有者,如果不是抛出异常。然后检查释放后写锁的线程数是否为0,如果为0则表示写锁空闲了,释放锁资源将锁的持有线程设置为null,否则释放仅仅只是一次重入锁而已,并不能将写锁的线程清空。

说明:此方法用于释放写锁资源,首先会判断该线程是否为独占线程,若不为独占线程,则抛出异常,否则,计算释放资源后的写锁的数量,若为0,表示成功释放,资源不将被占用,否则,表示资源还被占用。

总结

6.1 state 解析 private volatile int state;

int 类型占有 4个字节一个字节8位,所以 state 一个 32 位,高 16 位 代表读锁 低 16 位代表 写锁。

// 0x0000FFFF 16 进制 // 1111111111111111 2 进制 // 65535 10 进制 static final int SHARED_SHIFT = 16; static final int SHARED_UNIT = (1 << SHARED_SHIFT); // 65536 static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1; //65535 // 1111111111111111 static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; // 65535 // 1111111111111111

如果此时同步状态位 c 那么获取写状态 c & EXCLUSIVE_MASK
如果此时同步状态位 c 那么获取读状态 c >>>16 无符号补0,右移16位

6.2 注意

以上便是ReentrantReadWriteLock中写锁的分析,下一篇文章将是Condition的分析,如有错误之处,帮忙指出及时更正,谢谢,如果喜欢谢谢点赞加收藏加转发(转发注明出处谢谢!!!)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwyjzd.html