可重入锁条件公平
我对ReentrantLock's感到困惑Condition。这是文档:
等待线程按 FIFO 顺序发出信号。
从等待方法返回的线程重新获取锁的顺序与最初获取锁的线程相同,在默认情况下未指定,但对于公平锁,那些等待时间最长的线程优先。
根据最新的子弹,公平性带来了对信令重新获取锁定的明确指定的顺序。
但是第一个子弹的含义是什么?等待线程按 FIFO 顺序发出信号?我认为在这种情况下,信令仅意味着“信令”,这意味着它以 FIFO 顺序“解除”线程,但唤醒时的实际重新获取顺序受公平性控制。
HotSpot 内部有相当多的员工与 cxq 和等待队列相关联,我不太了解(不幸的是)。
问题:
不等待线程在FIFO顺序信号是否意味着等待的线程在他们停(即使锁本身是不公平的)相同的顺序取消驻留?
公平性是否提供了重新获取排序保证,因为在一般情况下存在 unpark-require 竞赛,这是必要的?
回答
如“fair”和“unfair”锁之间的内部存储差异中所述,“fair”和“unfair”之间的实际区别不是队列的组织,而是在不公平模式下,尝试获取锁的线程可能即使队列中已经有等待线程也成功。这样的超车线程根本不会与队列交互。
调用awaita上的方法之一的线程Condition必须已经拥有关联的锁并将释放它,以便另一个线程可以获取它,满足条件并调用signalor signalAll。因此该线程必须将自己排入队列,以便另一个线程知道要向哪个线程发出信号。当signal被调用时,该线程等待状态时间最长的是从FIFO中取出。
发出信号的线程可能会被解除停放,但也有可能它尚未停放。在任何一种情况下,它都必须重新获取锁,并且此重新获取受锁的公平保证的约束。到线程调用时,signal它必须拥有锁。因此,发出信号的线程不能立即成功。当锁被释放时,多个线程之间可能会发生竞争。
但是,条件的 FIFO 顺序中的信号意味着当两个或多个线程在同一条件下等待并且一个被发出信号时,它将是最长的等待线程并且其他线程都无法超越,即使对于不公平的锁也是如此。只有当多个线程被发信号或者其他线程,不等待条件,尝试获取锁时,不公平锁的获取顺序是任意的。此外,正如链接的答案所提到的,tryLock()即使在公平锁上也可能超过。