当前位置: 首页 > news >正文

ReentrantLock底层原理

ReentrantLock

在这里插入图片描述

public ReentrantLock() {sync = new NonfairSync();
}public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();
}

ReentrantLock 的默认实现是非公平锁,实际上 ReentrantLock 中的方法,几乎都让 sync 实现

实现原理

  • lock原理
    compareAndSetState(0,1),尝试将state从0=>1,成功,设置exclusiveOwnerThread=当前线程,否则tryAcquire根据 state 再次尝试获取,如果当前线程为exclusiveOwnerThread获得锁的线程,则state++(可重入),否则返回false。获取当前节点的前驱节点,tryAcquire,失败将前驱节点的waitStatus设为-1,阻塞直到拥有锁的线程释放。

在这里插入图片描述

  • unlock原理
    tryRelease,state–,更新state,直到state=0 —> setExclusiveOwnerThread(null),返回true,释放锁,唤醒阻塞的线程(可重入)。

释放锁的实现是不公平的,如果在 AQS队列中,head唤醒了后继节点竞争锁,同时又有一个线程也要竞争锁,那么它们都参与竞争锁,如果被唤醒的线程竞争失败,则再次阻塞,等待下次锁释放。

在这里插入图片描述

非公平锁的实现原理:刚来的线程可以和阻塞队列中唤醒的线程一起竞争,而不需要进入 AQS队列 中排队获取锁。

在这里插入图片描述
获取不到锁的线程进入 AQS队列中阻塞等待,直到被唤醒,如果期间被打断,设置打断标记为 true,但是当前线程仍在AQS队列中,所以 ReentrantLock 是不可打断的。

  • 公平锁的实现与非公平锁的实现主要是 tryAcquire 方法的实现
public final boolean hasQueuedPredecessors() {Node t = tail; Node h = head;Node s;return h != t &&((s = h.next) == null || s.thread != Thread.currentThread());
}
public final boolean hasQueuedPredecessors() {Node t = tail; Node h = head;Node s;return h != t &&((s = h.next) == null || s.thread != Thread.currentThread());
}

当AQS队列中有多个节点(线程阻塞),并且 如果第一个等待被唤醒的线程==null或第一个等待被唤醒的线程不是当前尝试获取锁的线程,返回true。则无法获取锁。

实际上就是对AQS队列中和外部尝试竞争锁的线程进行判断,即必须在AQS队列中排队获取锁

http://www.lryc.cn/news/368854.html

相关文章:

  • 基于JSP的医院远程诊断系统
  • 项目:基于httplib/消息队列负载均衡式在线OJ
  • 详解python中的pandas.read_csv()函数
  • 速盾:DDoS高防IP上设置转发规则
  • 京东一面测开(KPI)
  • Django框架中级
  • cordova-plugin-inappbrowser内置浏览器插件
  • 打造智慧工厂核心:ARMxy工业PC与Linux系统
  • Java File IO
  • MySQL 函数与约束
  • 12_1 Linux Yum进阶与DNS服务
  • Spring Boot集成geodesy实现距离计算
  • 在Windows上用Llama Factory微调Llama 3的基本操作
  • 01——生产监控平台——WPF
  • 33、matlab矩阵分解汇总:LU矩阵分解、Cholesky分解和QR分解
  • C语言——使用函数创建动态内存
  • 【PL理论】(16) 形式化语义:语义树 | <Φ, S> ⇒ M | 形式化语义 | 为什么需要形式化语义 | 事实:部分编程语言的设计者并不会形式化语义
  • 前端杂谈-警惕仅引入一行代码言论
  • 有关cookie配置的一点记录
  • Oracle如何定位硬解析高的语句?
  • Linux卸载残留MySQL【带图文命令巨详细】
  • 4句话学习-k8s节点是如何注册到k8s集群并且kubelet拿到k8s证书的
  • 2024全国大学生数学建模竞赛优秀参考资料分享
  • QPS,平均时延和并发数
  • 【Python核心数据结构探秘】:元组与字典的完美协奏曲
  • Golang | Leetcode Golang题解之第137题只出现一次的数字II
  • Spring和SpringBoot的特点
  • 怎么使用join将数组转为逗号分隔的字符串
  • Web前端博客论坛:构建、运营与用户体验的深度解析
  • Java从入门到放弃