【Java并发】ReentrantLock的实现原理

ReentrantLock是什么?

synchronized关键字是一种隐式锁,即它的加锁与释放是自动的,无需我们关心。而ReentrantLock是一种显式锁,需要我们手动编写加锁和释放锁的代码。
相对于synchronized它具备以下特点:

  • 可中断
  • 可以设置超时时间
  • 可以设置公平锁
  • 支持多个条件变量
  • 与synchronized一样,都支持重入(同一线程

例如:手动枷锁和解锁
在这里插入图片描述

注意被ReentrantLock加锁区域必须用try代码块包裹,且释放锁需要在finally中来避免死锁。执行几次加锁,就需要几次释放锁。

ReentrantLock底层源码:

在这里插入图片描述
点进去ReentrantLock的源码可以看到:
在这里插入图片描述
在这里插入图片描述
ReentrantLock实现了Lock接口

public interface Lock {
    // 获取锁
    void lock();
    // 获取可中断锁,即在拿锁过程中可中断,synchronized是不可中断锁。
    void lockInterruptibly() throws InterruptedException;
    // 尝试获取锁,成功返回true,失败返回false
    boolean tryLock();
    // 在给定时间内尝试获取锁,成功返回true,失败返回false
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    // 释放锁
    void unlock();
    // 等待与唤醒机制
    Condition newCondition();
}

在Lock中定义了多个获取锁的方法,以及释放锁的方法。同时还有一个与等待与唤醒机制有关系的newCondition方法

继续往下看Sync类是继承了AQS类(抽象队列同步器)的
在这里插入图片描述

ReentrantLock底层原理图解:(以NonfairSync举例)

  • exclusiveOwnerThread 表示独占当前锁的线程
  • head与tail 分别表示了等待线程队列的头结点和尾结点;
  • state 表示同步的状态,为0时表示未加锁状态,而大于0时表示加锁状态

在这里插入图片描述

  1. 线程来抢锁后使用cas的方式修改state状态,修改状态成功为1,则让exclusiveOwnerThread属性指向当前线程,获取锁成功
  2. 假如修改状态失败,则会进入双向队列中等待,head指向双向队列头部,tail指向双向队列尾部
  3. 当exclusiveOwnerThread为null的时候,则会唤醒在双向队列中等待的线程公平锁则体现在按照先后顺序获取锁,非公平体现在不在排队的线程也可以抢锁
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值