Lock.unlock()源码解析

本文深入探讨Java8中ReentrantLock的源码实现,解析锁的获取与释放流程,以及同步队列中节点的多种状态,包括CANCELLED、SIGNAL、CONDITION和PROPAGATE,帮助读者理解ReentrantLock的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Lock 源码个人理解 (java8)

ReentrantLock lock = new ReentrantLock();
        
        lock.lock();
        
        lock.unlock();
waitStatus节点的几种状态:
  • CANCELLED,值为1,由于在同步队列中等待的线程等待超时或者被中断,需要从同步队列中取消等待,节点进入该状态将不会变化。

  • SIGNAL,值为-1,后继节点的线程处于等待状态,而当前节点的线程如果释放了同步状态或者被取消,将会通知后继节点,使后继节点得以运行。

  • CONDITION,值为-2,节点在等待队列中,节点线程等待在Condition上,当其他线程对Condition调用了signal()方法后,该节点将会从等待队列中转移到同步队列中,加入到对同步状态的获取中。

  • PROPAGATE,值为-3,表示下一次共享式同步状态获取将会无条件地被传播下去。
    INITAL,值为0,初始状态。

reentrantLock 的 lock.unlock()开始执行

在这里插入图片描述
在这里插入图片描述

先来看看tryRelease (尝试释放锁)

在这里插入图片描述

  • 先获取当前锁的上锁次数 getState()
    • 一个线程拿到锁 state = 1
    • 当前线程锁重入 state+=1
  • 当前线程上锁次数-1
  • 判断当前线程是否是独占线程
    • 不是,报错
  • 如果上锁次数为0
    • 释放独占线程
  • 更新上锁次数
回到release方法

在这里插入图片描述

  • 拿到队列的第一个线程
  • 如果第一个线程不等于null 且 状态不是完成状态
  • 执行unparkSuccessor(顾名思义 释放park住的线程)

在这里插入图片描述

  • 如果队列头节点状态小于0
  • 修改头部节点为初始状态
  • 那头线程的下一个线程
    • 如果为null 或者 状态大于0
    • 拿里头部最近的一个状态小于0的节点
  • 唤醒这个节点,让其争取锁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值