
文章插图
根据调用链路,实际的加锁逻辑在Sync.nonfairTryAcquire方法里面 。
abstract static class Sync extends AbstractQueuedSynchronizer {// 非公平锁的最终加锁方法final boolean nonfairTryAcquire(int acquires) {final Thread current = Thread.currentThread();// 1. 获取同步状态int c = getState();// 2. state=0表示无锁,先尝试加锁(使用CAS设置state=1)if (c == 0) {if (compareAndSetState(0, acquires)) {// 3. 加锁成功,就把当前线程设置为持有锁线程setExclusiveOwnerThread(current);return true;}// 4. 如果当前线程已经持有锁,执行可重入的逻辑} else if (current == getExclusiveOwnerThread()) {// 5. 加锁次数+acquiresint nextc = c + acquires;// 6. 超过tnt类型最大值,溢出了if (nextc < 0)throw new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;}}再看一下释放锁的调用流程 , 公平锁和非公平锁流程是一样的,最终都是执行Sync.tryRelease方法:
文章插图
abstract static class Sync extends AbstractQueuedSynchronizer {// 释放锁protected final boolean tryRelease(int releases) {// 1. 同步状态减去释放锁次数int c = getState() - releases;// 2. 校验当前线程不持有锁,就报错if (Thread.currentThread() != getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free = false;// 3. 判断同步状态是否等于0 , 无锁后,就删除持有锁的线程if (c == 0) {free = true;setExclusiveOwnerThread(null);}setState(c);return free;}}再看一下公平锁的源码3.3 公平锁源码先看一下公平锁的加锁流程:

文章插图
最终的加锁方法是FairSync.tryAcquire,看一下具体逻辑:
static final class FairSync extends Sync {// 实现父类的加锁逻辑protected final boolean tryAcquire(int acquires) {final Thread current = Thread.currentThread();// 1. 获取同步状态int c = getState();// 2. state=0表示无锁,先尝试加锁(使用CAS设置state=1)if (c == 0) {// 3. 判断当前线程是不是头节点的下一个节点(讲究先来后到)if (!hasQueuedPredecessors() &&compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}// 4. 如果当前线程已经持有锁,执行可重入的逻辑} else if (current == getExclusiveOwnerThread()) {// 5. 加锁次数+acquiresint nextc = c + acquires;// 6. 超过tnt类型最大值,溢出了if (nextc < 0)throw new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;}// 判断当前线程是不是头节点的下一个节点(讲究先来后到)public final boolean hasQueuedPredecessors() {Node t = tail;Node h = head;Node s;return h != t &&((s = h.next) == null || s.thread != Thread.currentThread());}}公平锁的释放锁逻辑跟非公平锁一样,上面已经讲过 。4. 总结看完了ReentrantLock的所有源码,是不是觉得ReentrantLock很简单 。
由于加锁流程的编排工作已经在父类AQS中实现,子类只需要实现具体的加锁逻辑即可 。
加锁逻辑也很简单,也就是修改同步状态state的值和持有锁的线程exclusiveOwnerThread 。
我是「一灯架构」,如果本文对你有帮助,欢迎各位小伙伴点赞、评论和关注,感谢各位老铁,我们下期见

文章插图
【干货,深入剖析ReentrantLock源码,推荐收藏】
推荐阅读
- 【深入浅出 Yarn 架构与实现】2-4 Yarn 基础库 - 状态机库
- 硬核剖析Java锁底层AQS源码,深入理解底层架构设计
- 一 OpenMP 教程 深入人剖析 OpenMP reduction 子句
- 【深入浅出 Yarn 架构与实现】2-2 Yarn 基础库 - 底层通信库 RPC
- Helm干货!速度围观!
- 【深入浅出 Yarn 架构与实现】2-1 Yarn 基础库概述
- 【深入浅出 Yarn 架构与实现】1-2 搭建 Hadoop 源码阅读环境
- 【深入浅出 Yarn 架构与实现】1-1 设计理念与基本架构
- clip-path属性深入理解与使用
- 一 Pthread 并发编程——深入剖析线程基本元素和状态
