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队列中排队获取锁

相关推荐

  1. ReentrantLock

    2024-06-11 00:24:01       40 阅读
  2. ReentrantLock 原理你都知道吗?

    2024-06-11 00:24:01       39 阅读
  3. 【源码解析】从ReentrantLock角度聊聊AQS原理

    2024-06-11 00:24:01       47 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-11 00:24:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-11 00:24:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-11 00:24:01       82 阅读
  4. Python语言-面向对象

    2024-06-11 00:24:01       91 阅读

热门阅读

  1. 本地部署 RAGFlow

    2024-06-11 00:24:01       37 阅读
  2. RGMII接口--->(013)FPGA实现RGMII接口(十三)

    2024-06-11 00:24:01       31 阅读
  3. 开机自启动脚本配置

    2024-06-11 00:24:01       31 阅读
  4. 本地化平台部署运维事项

    2024-06-11 00:24:01       34 阅读
  5. 软件安全技术【太原理工大学】

    2024-06-11 00:24:01       31 阅读
  6. 数据结构——第8章 排序

    2024-06-11 00:24:01       31 阅读
  7. React的生命周期总结

    2024-06-11 00:24:01       31 阅读
  8. 02--SpringBoot自动装配原理

    2024-06-11 00:24:01       38 阅读
  9. c 语言 ---- 结构体

    2024-06-11 00:24:01       27 阅读
  10. C++入门7 类|构造函数|析构函数

    2024-06-11 00:24:01       21 阅读
  11. linux Ubuntu安装samba服务器与SSH远程登录

    2024-06-11 00:24:01       34 阅读
  12. MC服务器怎么搭建

    2024-06-11 00:24:01       32 阅读