【问题标题】:Reentrant lock condition fairness可重入锁条件公平
【发布时间】:2021-04-18 08:21:11
【问题描述】:

我对@9​​87654322@ 的Condition 感到困惑。这是文档:

  • 等待线程按 FIFO 顺序发出信号。

  • 等待返回的线程重新获取锁的顺序 方法与最初获取锁的线程相同,即 在默认情况下未指定,但对于公平锁有利于那些 等待时间最长的线程。

根据最新的子弹,公平性带来了一个明确的信号锁定重新获取顺序。

但第一个项目符号的含义是什么等待线程以 FIFO 顺序发出信号?我认为在这种情况下,信号仅意味着“信号”,这意味着它按照 FIFO 顺序“解除”线程,但唤醒时的实际重新获取顺序由公平性决定。

There are pretty large amount of staff 与 cxq 绑定,并且 HotSpot 内部的等待队列我不太了解(不幸的是)。


问题

等待线程按 FIFO 顺序发出信号是否意味着等待线程按照它们被停放的顺序解除停放(即使锁本身是不公平的)?

由于一般情况下存在 unpark-reaquire 竞赛,公平性是否提供了必要的重新获取排序保证?

【问题讨论】:

  • 至于第一个问题,FIFO -> 先进先出,所以信令不是按照相反的顺序进行的,而是按照相同的顺序进行的
  • @areus 当然,谢谢。
  • 您链接的mutex.cpp 与Java 类ReentrantLock 无关。该本机代码用于实现synchronized,它根本没有公平模式。
  • @Holger 它委托给 Unsafe.park,而 Unsafe.park 本身又委托给 static ParkCommon
  • 但是parkunpark的实现与ReentrantLock内部的队列实现完全无关。 AbstractQueuedSynchronizer.

标签: java multithreading jvm hotspot


【解决方案1】:

阅读 ReentrantLock (Java 12) 的源码我们可以看到,与公平和不公平 ReentrantLock 的区别很小。不同之处在于扩展 java.util.concurrent.locks.AbstractQueuedSynchronizer 的类。在一种情况下是 FairSync,在另一种情况下是 NonfairSync。两者都在 ReentrantLock 中定义,唯一的区别是 FairSync 在方法 tryAcquire 中实现了一项检查。 阅读代码似乎在最佳条件下也在非公平 ReentrantLock FIFO 得到尊重,但由于取消、超时或类似情况,这不能保证。在公平的 ReentrantLock 中,获取锁之前的任何线程(如果从队列中取消驻留)重新检查是否有较旧的线程。 我不确定是否理解第二个问题,但请注意释放锁的线程已从队列中取消驻留线程。此外,如果释放锁的线程解除了队列中较旧的线程的停放,这不足以避免starvation,因为第三个线程可能需要在退出线程解除等待的线程之前同时获得锁。在公平模式下,每次有新线程尝试获得锁时,都会检查所有等待的线程,并且此被授予者 FIFO 并避免饥饿。

等待线程的外部中断不会改变队列顺序。

【讨论】:

    【解决方案2】:

    正如Difference in internal storing between 'fair' and 'unfair' lock 中所解释的,“公平”和“不公平”之间的实际区别不是队列的组织,而是在不公平模式下,即使已经等待,尝试获取锁的线程也可能成功队列中的线程。这样的超车线程根本不会和队列交互。

    Condition 上调用await 方法之一的线程必须已经拥有关联的锁并将释放它,以便另一个线程可以获取它,满足条件并调用signalsignalAll。所以线程必须自己入队,以便其他线程知道要向哪个线程发出信号。当signal被调用时,从FIFO中取出等待条件时间最长的线程。

    已发出信号的线程可能未停放,但也有可能尚未停放。在任何一种情况下,它都必须重新获取锁,并且这种重新获取受锁的公平保证。当一个线程调用signal 时,它必须拥有锁。因此,发出信号的线程不能立即成功。当锁被释放时,可能会出现多个线程之间的竞争。

    但是一个条件的 FIFO 顺序的信号意味着当两个或多个线程在相同的条件上等待并且一个得到信号时,它将是等待时间最长的线程并且其他线程都不能超过,即使是不公平的锁.只有当多个线程发出信号或其他线程,不等待条件时,才尝试获取锁,不公平锁的获取顺序是任意的。此外,正如链接的答案所提到的,tryLock() 即使在公平锁定上也可能超过。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多