【问题标题】:Java Reentrant lock dead lockJava 可重入锁死锁
【发布时间】:2021-06-08 00:38:34
【问题描述】:

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

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

【问题讨论】:

  • 死锁是指您有两个或多个线程拥有锁并且每个线程都试图获取另一个线程的锁。你描述的情况不会是僵局。不要滥用标准术语。
  • 好的,谢谢,但我应该怎么称呼这个,也许,永不醒来的停车场?
  • 实际上不确定。错误?
  • 我没有遇到这种情况,但我只是想知道为什么不会发生这种情况。
  • 任何时候程序的结果取决于不同线程的执行是如何交错的,你可以称之为“竞争条件”。如果任何可能的结果是可接受的,有些人更喜欢说“数据竞争”,而如果一个或多个可能的结果是坏/错误的,他们只会说“竞争条件”。

标签: java concurrency reentrantlock


【解决方案1】:

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

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

所以acquireQueued 是否需要一分钟或更长时间才能到达park 并不重要,因为前面对unpark 的调用已经为线程提供了许可。许可证将被撤销而不阻塞。

【讨论】:

  • 谢谢,我重新检查了文档,确实如此!