@lovely 2023-06-30 18:13 采纳率: 86.4%
浏览 19

Java可重入锁怎么释放资源的

在读ReentrantLock重入锁的源码读的不是很懂

img

1、我发现,当重入锁释放资源的时候是通过判断头节点的的waitStatus是否小于0小于0则释放该锁,但释放锁的时候,会将该头节点的waiteStatus设置为0标识该头节点,为一个无用的节点
2、当执行释放锁的动作时,如果发现当前线程因为某些原因被取消的时候,就会从链表的尾部,往前面找一个watStatus=-1的节点进行锁的释放

3、当将头节点设置为0之后,如果后面又有线程执行锁的释放该怎么办
4、当发现当前需要释放锁的线程被取消了之后,就从尾节点向前找一个节点进行释放,这样真的好吗,万一释放错了呢

  • 写回答

2条回答 默认 最新

  • PhoenixRiser 2023-06-30 18:22
    关注

    TechWhizKid参考GPT回答:

    1. waitStatus在阻塞队列中是一个重要的属性,它表示节点的状态。这个属性有几个关键值:CANCELLED (1) 表示当前的线程被取消;SIGNAL (-1) 表示当前节点的后继节点包含的线程需要运行,也就是说前驱节点释放同步状态后需要通知后继节点;等等。当 waitStatus 小于 0 时,也就是值为 SIGNAL 或者 CONDITION 或者 PROPAGATE,说明当前的线程是在等待同步状态。所以,当头节点的状态小于0,那么释放锁,否则,不释放。

    2. 如果当前线程被取消(waitStatus设为CANCELLED),从队尾向前寻找waitStatus<=0的节点是为了保证锁的公平性,而且队列中的每个节点都记录了其前驱和后继,所以这样设计可以尽可能减少对队列的遍历,从而提高效率。

    3. 如果将头节点的waitStatus设为0,那么此时如果有线程试图释放锁,因为这个节点的waitStatus不小于0,所以不会释放,这样保证了公平性。这个头节点的waitStatus会在后续的操作中被修改。

    4. 如果当前需要释放锁的线程被取消,那么从尾节点向前寻找一个节点进行释放,这种做法并不会释放错。因为每个节点都保存了对应线程的引用,而且链表中的节点顺序是等待获取锁的线程顺序,这就保证了公平性。无论是从头部还是从尾部找到的第一个待释放的节点(waitStatus<=0),都是最应该获取锁的线程。

    评论

报告相同问题?

问题事件

  • 创建了问题 6月30日

悬赏问题

  • ¥60 QQOP数据,什么是op数据号,怎么提取op数据!能不能大量提取(语言-c语言)
  • ¥15 matlab代码 关于微分方程和嵌套的分段函数。
  • ¥15 把VMware项目复制到另一台电脑
  • ¥15 onlyoffice编辑完后立即下载,下载的不是最新编辑的文档
  • ¥15 求caverdock使用教程
  • ¥15 Coze智能助手搭建过程中的问题请教
  • ¥15 12864只亮屏 不显示汉字
  • ¥20 三极管1000倍放大电路
  • ¥15 vscode报错如何解决
  • ¥15 前端vue CryptoJS Aes CBC加密后端java解密