Java 当锁不立即可用时,调用Lock.Lock()的线程何时从调用返回?

Java 当锁不立即可用时,调用Lock.Lock()的线程何时从调用返回?,java,multithreading,concurrency,synchronization,Java,Multithreading,Concurrency,Synchronization,来自文档: Condition.signalAll()的文档说明 '唤醒所有等待的线程。 如果有线程在这种情况下等待,那么它们都会被唤醒。每个线程必须重新获取锁,然后才能从wait返回 如上所述正在等待的线程包括调用 条件。等待(…) 其文档说明“与此条件相关的锁被自动释放,当前线程出于线程调度目的被禁用,并处于休眠状态,直到…” 讨论案例: 因此,假设一个线程在调用Condition.await(…)后,出于线程调度目的而被禁用,处于休眠状态,然后在另一个线程调用Condition.signa

来自文档:

Condition.signalAll()的文档说明

'唤醒所有等待的线程。 如果有线程在这种情况下等待,那么它们都会被唤醒。每个线程必须重新获取锁,然后才能从wait返回

如上所述正在等待的线程包括调用

条件。等待(…)

其文档说明“与此条件相关的锁被自动释放,当前线程出于线程调度目的被禁用,并处于休眠状态,直到…”

讨论案例: 因此,假设一个线程在调用
Condition.await(…)
后,出于线程调度目的而被禁用,处于休眠状态,然后在另一个线程调用
Condition.signalAll()
时被唤醒,并且在返回等待之前与其他线程竞争重新获取锁

因此,我认为,线程必须从其禁用状态中唤醒(线程调度目的),并在获取锁之前进行竞争

标题中的问题:

Lock.Lock()
的文档中说

'如果锁不可用,则出于线程调度目的,当前线程将被禁用,并处于休眠状态,直到获得锁为止。'

现在,对于一个出于线程调度目的而被禁用并处于休眠状态的线程,如果它调用
lock()
方法时锁不可用,该怎么办

这样一个线程什么时候才能从禁用状态中醒来并进行竞争,从而获得锁

注意:

一,。所有提到的
条件
对象都是指从讨论中的同一
对象获得的单一条件对象


二,。隐式锁中不会出现这种情况,因为调用同步代码的所有线程只是相互阻塞,并在不禁用自身的情况下竞争锁。

该线程出于调度目的被禁用,这意味着它不会获得CPU时间,但它仍在等待获取锁。因此,它不是处于
RUNNABLE
状态,而是处于
WAITING
状态

当锁被释放时,线程有机会获取它或停留在
等待中
,该过程将重复<代码>条件
似乎与此问题没有任何关系

因此,我认为,线程必须从其禁用状态中唤醒(线程调度目的),并在获取锁之前进行竞争

对。一些系统将锁预先分配给线程,然后作为“释放锁”过程的一部分重新启用它以进行调度。但更典型的设计只是重新调度线程,让它竞争锁

现在,如果一个线程由于线程调度而被禁用,并且处于休眠状态,那么该线程会怎么样呢?因为在调用lock()方法时,锁不可用

这样一个线程什么时候才能从禁用状态中醒来并进行竞争,从而获得锁


通常,只要持有锁的线程将其释放。典型的实现是,线程在禁用自身之前将自身添加到等待锁定的线程列表中。当锁被释放时,释放锁的线程将检查该列表,并且列表中至少有一个线程被重新启用。

我不理解您的困惑。它表示在获取锁之前处于休眠状态。它表示在当前线程获取锁之前处于休眠状态。请参阅
lockinterruptbly()
的文档,因为
lock()
lockinterruptbly()
相同,只是
lock()
方法不会引发异常。我只是不知道当前线程获取锁的场景,因为它从不醒来获取锁会让它醒来。或者你在问获取是如何工作的?你被英语卡住了。当线程唤醒时,它被认为已获得锁。获取技术是一个实现细节。那么,您是说等待锁定的线程列表中有活动的线程(即通过
条件.signalAll()
唤醒的线程)以及通过
锁定.lock()禁用的线程。但是这样的列表不应该包含通过另一个条件的
await(…)
方法禁用的线程,因为这些线程除非得到通知,否则不会获取锁,不是吗?这是一种可能的实现,是的。等待竞争禁用的锁的线程在列表中。当线程释放锁时,会检查该列表。我终于明白每个实现都是有意义的,我问的问题是实现细节的一部分。