问题描述
为什么java可重入锁不会导致死锁?
我正在研究可重入锁,并且确实意识到尝试获取失败的线程将被放置在同步队列中,并且在它停放之前,它将其prev节点的waitStatus设置为SIGNAL,并重新检查prev节点是否已设置其stat 为 0,如果不是,则可以确定 prev 节点尚未取消停放它,因为它尚未清除 SIGNAL 状态,因此它停放。但是如果间隔 shoudParkAFterFailedAcquire 和 parkAndCheckInterrrupt 需要,比如说 1 秒或 1 分钟, 所以 unpark 在停车前先到达。这会导致僵局吗?
解决方法
park
和 unpark
不像您想象的那样工作。它们基于类似许可证的系统:
- 当一个线程被解除停放时,如果它还没有一个“许可”,它就会被授予一个“许可”。
- 当一个线程调用
park
时,它会阻塞直到它有一个许可并且许可被撤销。如果在调用park
时它已经有一个许可,那么它根本不会阻塞。
所以 acquireQueued
到达 park
需要一分钟或更长时间没有关系,因为前面对 unpark
的调用已经为线程提供了许可.许可证将在不阻塞的情况下被撤销。