我认为源代码可以为我们提供更多关于它如何工作的线索。ReentrantLock.newCondition() 在AbstractQueuedSynchronizer中返回一个ConditionObject 。这里是源代码链接AQS 源代码。
1. 等待线程以 FIFO 顺序发出信号。
AbstractQueuedSynchronizer中有两个队列。
一个是等待锁(就叫它锁等待队列),你会在
AbstractQueuedSynchronizer的类定义中看到两个 volatile 变量头和尾,公平参数会影响这个队列的行为。当你新建一个公平的ReentrantLock并调用获取时,AQS 会调用FairSync的tryAcquire来检查当前线程是否是锁等待队列中等待的第一个线程,参见hasQueuedPredecessors。
另一个队列是ConditionObject定义中的信号队列,你会看到两个变量firstWaiter和lastWaiter。当调用await时,一个节点将添加到队列的尾部,当调用信号时,头部的一个节点将出队并添加到锁等待队列重新获取锁。添加到锁等待队列并不意味着它会被唤醒,而是在信号之后会调用一个Lock.unlock(),这将唤醒等待者,见unparkSuccessor .
2.从等待方法返回的线程重新获取锁的顺序与最初获取锁的线程相同,默认情况下未指定,但公平锁优先考虑等待时间最长的线程。
从await方法中唤醒并不意味着持有锁,它会调用acquireQueued重新获取锁并可以再次停放。在我的理解中,最初获取锁的顺序与调用await的顺序相同,因此与调用acquireQueued的顺序相同,但让我感到困惑的是,公平锁偏爱那些等待时间最长的线程。,当从await中唤醒时,在我看来,它将是锁等待队列中的第一个线程,当调用acquireQueued并检查p == head && tryAcquire(arg)时,锁是否公平没有影响。
希望这会有所帮助,如果我错了,请告诉我。