java基础-并发编程-ReentrantLock源码学习

ReentrantLock源码

大纲

AQS结构

非公平锁nonfairTryAcquires实现

公平锁TryAcquires实现

获取锁失败,将线程添加到链表:addWaiter

队列为空或CAS修改链表尾节点失败,将当前节点设置为尾节点

尝试再次获取锁,未获取到锁则挂起当前节点线程

java 复制代码
final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {//死循环
                final Node p = node.predecessor();//获得该node的前置节点
                /**
                * 如果前置节点是head,表示之前的节点就是正在运行的线程,表示是第一个排队的
(一般讲队列中第一个是正在处理的,可以想象买票的过程,第一个人是正在买票(处理中),第二个才是真正排队的人);
那么再去tryAcquire尝试获取锁,如果获取成功,说明此时前置线程已经运行结束,则将head设置为当前节点返回
                *
                *
                **/
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC,将前置节点移出队列,这样就没有指针指向它,可以被gc回收
                    failed = false;
                    return interrupted;//返回false表示不能被打断,意思是没有被挂起,也就是获得到了锁
                }
                /**shouldParkAfterFailedAcquire将前置node设置为需要被挂起,
                    注意这里的waitStatus是针对当前节点来说的,
                    即是前置node的ws指的是下一个节点的状态**/
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())//挂起线程 park()
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);//如果失败取消尝试获取锁(从上面的代码看只有进入p == head && tryAcquire(arg)这个逻辑是才会触发,这个时候前置节点正好在当前节点入队的时候执行完,当前节点正好获得锁,具体的代码以后分析)
        }
    }
//看到因为是死循环,所以当执行到parkAndCheckInterrupt()时,当前线程被挂起,等到某一天被unpark继续执行,这个时候已经是对头的第二个节点了,那么就会进入if (p == head && tryAcquire(arg))逻辑获取到锁并结束循环

获取锁失败后判断当前线程是否可以被挂起

释放锁

根据state值是否为0判断重入锁是否释放为0

唤醒被挂起的线程

相关推荐
看浪的路人几秒前
第9讲:大模型应用监控与可观测性——OpenTelemetry + Prometheus + Grafana 全链路追踪
java·前端·spring
临床数据科学和人工智能兴趣组11 分钟前
在R语言的生态系统中,字符串处理一直是一个重要且复杂的任务
开发语言·正则表达式·r语言·r语言-4.2.1
大侠归来11 分钟前
事务能回滚吗?Pipeline 算事务吗?
java·数据库·oracle
蜗牛互联网12 分钟前
Python调用Gemini Structured Outputs实现工单路由门禁
java·开发语言·人工智能·python
SEO_juper28 分钟前
给网页做可引用性评分:判断内容够不够让 AI 引用(GEO 工具,附代码)
开发语言·人工智能·爬虫·python·seo·独立站
Wang's Blog32 分钟前
Java 项目实战: 交友项目 - 产品定位、功能模块与客户端原型解读
java·开发语言·交友
Wang's Blog35 分钟前
Java 项目实战:交友项目 —— 项目导读与整体架构
java·架构·交友
wdfk_prog1 小时前
LWIP教程 16:从 MTU 到 `ip4_frag()` / `ip4_reass()`——IPv4 分片、重组、超时与内存压力
运维·服务器·网络·笔记·学习
今年下半年1 小时前
【短信发送】Spring Boot整合多种短信接口的实现(附源码)
java·spring boot·后端·sms·qcloudsms
Xudde.1 小时前
AI-Web1 靶机渗透测试(Vulnhub Writeup)
笔记·学习·安全·web安全