当前位置:网站首页>ReentrantLock学习之---释放锁过程
ReentrantLock学习之---释放锁过程
2022-07-26 18:05:00 【virtuousOne】
ReentrantLock不像sync可以自动释放锁,它需要手动释放,否则就会出现死锁情况。
public void unlock() {
sync.release(1);
}
在release()中,通过 tryRelease() 来判断释放锁的情况。
先看tryRelease()方法
校验了当前线程是否是占用锁线程,不是会直接抛出异常
同时判断 statet状态是否为0 ,是说明是完全释放了锁,更新state的值。 不是则啥都不操作。
@ReservedStackAccess
protected final boolean tryRelease(int releases) {
// 减去释放的值
int c = getState() - releases;
// 如果当前线程不是占用锁的线程,说明当前线程并没有持锁
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
// 当前线程持有锁 ,默认是false
boolean free = false;
// 如果成立,说明完全释放锁了
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
// 更新AQS state的值
setState(c);
return free;
}
在release()方法中,获取成功进入释放锁时,需要的操作是唤醒后继节点的操作.

获取当前的state值,如果小于0,说明是-1,当前状态为Signal状态。 当前节点已经完成了唤醒后继节点的操作,更新state的值为0即可。
当s == null 表示当前节点是tail节点, >0 说明当前节点的后继节点是取消状态,说明后继节点是取消状态,需要进行的操作是唤醒一个合适的节点。
通过for循环,找到一个最佳的可以被唤醒的node进行赋值给s.
如果s != null 说明找到了节点,直接唤醒s节点即可。
private void unparkSuccessor(Node node) {
// 获取当前节点的状态
int ws = node.waitStatus;
if (ws < 0) // -1 Signal状态 因为当前节点已经完成了唤醒后继节点的任务了
// 更新为 0
node.compareAndSetWaitStatus(ws, 0);
// s 为当前节点的后继节点
Node s = node.next;
// 条件一: s == null 表示当前节点是 tail节点
// 条件二: 说明当前node 节点的后继节点是取消状态
// 成立: 说明当前node节点的后继节点是取消状态, 需要找到一个合适的可以被唤醒的节点
if (s == null || s.waitStatus > 0) {
// 查找可以被唤醒的节点
s = null;
for (Node p = tail; p != node && p != null; p = p.prev)
if (p.waitStatus <= 0)
s = p;
// 循环可以找到一个距离当前node最近的一个可以被唤醒的node, node可能找到,也可以是null
}
//
if (s != null)
// 如果找到了,就唤醒
LockSupport.unpark(s.thread);
}
回到release()中,当前的head节点 已经被初始化, 且后继节点有值,才会进行唤醒后一个节点的操作。
也可以理解为,释放锁操作在tryRelease()方法中处理,处理完成后,如果不是最后一个节点还会继续唤醒后一个节点的操作。
public final boolean release(int arg) {
// 尝试释放锁: tryRelease 返回
if (tryRelease(arg)) {
// head 什么情况下被创建出来?
// 当持锁线程未被释放,且有其他线程想要获取锁时,其他线程发现获取不了锁,且队列为空队列
Node h = head;
// 条件一成立: 说明队列中的head节点已经初始化了
// 条件二成立: 说明当前head后面一定插入过 node节点
if (h != null && h.waitStatus != 0)
// 唤醒后继节点
unparkSuccessor(h);
return true;
}
return false;
}
边栏推荐
猜你喜欢

SSM整-整合配置

Write a starter

MySQL - multi table query and case explanation

5款WPS Office最佳海外替代品

2022 mobile crane driver test questions simulation test platform operation

MySQL - 多表查询与案例详解

Multi thread learning notes -1.cas

How many pairs can an array of leetcode simple questions form

Brian behrendorf, general manager of openssf Foundation: it is estimated that there will be 420million open sources in 2026

MySQL exercises elementary 45 questions (Unified table)
随机推荐
2022 chemical automation control instrument test question simulation test platform operation
【Swoole系列3.1】进程、线程、协程,面试你被问了吗?
How to become an excellent test / development programmer? Focus on planning and then move
这场竞赛,能读懂题目的你大有可为
[postgraduate entrance examination vocabulary training camp] day 13 - reliance, expert, subject, unconscious, photograph, exaggeration, counter act
Utility website recommendations
Write a starter
Tensorflow GPU 1.15 installation
简述MES系统的11大核心功能模块
Advanced template (runner's notes)
议程速递 | 7月27日分论坛议程一览
如何成为一名优秀的测试/开发程序员?专注谋定而后动......
【考研词汇训练营】Day 14 —— panini,predict,access,apologize,sense,transport,aggregation
NFT digital collection development: digital collections help enterprise development
Tensorflow-GPU 1.15安装
SD NAND与eMMC优劣势对比
支持代理直连Oracle数据库,JumpServer堡垒机v2.24.0发布
当前占位,之后再写
Daorayaki | product principles of non-financial decentralized application
MySQL - 函数及约束命令