Java 可重入锁死锁

问题描述

为什么java可重入锁不会导致死锁?

我正在研究可重入锁,并且确实意识到尝试获取失败的线程将被放置在同步队列中,并且在它停放之前,它将其prev节点的waitStatus设置为SIGNAL,并重新检查prev节点是否已设置其stat 为 0,如果不是,则可以确定 prev 节点尚未取消停放它,因为它尚未清除 SIGNAL 状态,因此它停放。但是如果间隔 shoudParkAFterFailedAcquire 和 parkAndCheckInterrrupt 需要,比如说 1 秒或 1 分钟, 所以 unpark 在停车前先到达。这会导致僵局吗?

enter image description here

解决方法

parkunpark 不像您想象的那样工作。它们基于类似许可证的系统:

  • 当一个线程被解除停放时,如果它还没有一个“许可”,它就会被授予一个“许可”。
  • 当一个线程调用 park 时,它会阻塞直到它有一个许可并且许可被撤销。如果在调用 park 时它已经有一个许可,那么它根本不会阻塞。

所以 acquireQueued 到达 park 需要一分钟或更长时间没有关系,因为前面对 unpark 的调用已经为线程提供了许可.许可证将在不阻塞的情况下被撤销。