英文:
based on which implementation does await and signalAll work
问题
以下是翻译好的部分:
我在阅读关于 Java 中的 reentrantlock
,以及如何通过在接口 Condition
中使用 newCondition()
方法来了解锁定条件。但是后来我在接口 Condition 的文档中看到用户必须为其使用提供实现。
实现注意事项:
在调用此方法时,假定当前线程持有与此 Condition 相关联的锁。由实现来确定是否为这种情况,如果不是,则确定如何响应。
话虽如此,由于过去的几天里,我一直在解决餐桌哲学家问题,不得不使用 signalAll()
和 await()
,而无需提供任何自定义的实现。
例如,我使用了这行代码:
((Philosopher) right).getNeighborCondition().await();
其中对象 right
声明如下:
Iphilosopher right = new Philosopher();
Iphilosopher
是一个接口,而 Philosopher
是实现它并继承了 Thread
的类。
当我点击 Ctrl + 鼠标左键单击
方法 await()
时,我会看到一个接口 void 方法,它会抛出 InterruptedException
。
那么在调用 await()
或 signalAll()
时使用了哪种实现呢?
英文:
I was reading about the reentrantlock
in java and how we can know the lock condition by using the newCondition()
method in the interface Condition
but then I saw in the documentation of the interface Condition that the user has to provide an implementation for its use.
>Implementation Considerations:
> The current thread is assumed to hold the lock associated with this Condition when this method is called. It is up to the implementation to determine if this is the case and if
not, how to respond.
that being said since couple of days i was working on the dining philosopher problem and had to use signalAll() and await() without any self-provided implementation!.
per example i used this line:
((Philosopher) right).getNeighborCondition().await();
where the Object right
is declared like this:
Iphilosopher right= new Philosopher();
Iphilosopher
is an interface and the Philosopher
is the class that implements it and extends Thread
.
when clicking Ctrl + left mouse click
on the method await()
I'm presented with an interface void method which throws InterruptedException
.
so which implementation is being used when await()
or signalAll()
are called?!
答案1
得分: 0
你对Javadoc的理解有些不正确。以下是你关注的 Condition#await()
的Javadoc部分:
实现注意事项
在调用此方法时,假定当前线程持有与此
Condition
关联的锁。由实现来确定是否为这种情况,如果不是,则如何响应取决于实现。通常会抛出异常(如IllegalMonitorStateException
),并且实现必须记录此事实。
这段话表达了三个要点:
- 当调用
await()
时,当前线程必须持有锁。这在前面的文档以及Lock#newCondition()
的文档中有进一步的支持:
在等待条件之前,当前线程必须持有锁。
Condition
的实现负责确定当前线程是否持有锁。- 如果当前线程 不 持有锁,则未指定应该发生什么。
- 接下来还提到,典型的实现会在这种情况下抛出
IllegalMonitorStateException
,并且实现必须对所选择的方法进行文档记录。
- 接下来还提到,典型的实现会在这种情况下抛出
在任何地方都没有说 用户 必须提供 Condition#await()
的实现。它只是说 Lock
(以及扩展为 Condition
)实现的 开发者 必须编写代码以符合契约,并提供必要的文档。
你提到了 ReentrantLock
,这是 Lock
的一个完整实现,所以让我们专注于这个类。以下是从 ReentrantLock#newCondition()
的文档摘录:
- 如果在调用任何
Condition
等待或信号方法时没有持有此锁,则会抛出IllegalMonitorStateException
。
这解决了上述的第三点。该文档说明了当线程在没有持有锁的情况下调用 await()
(以及每个相关方法)时,返回的 Condition
实例将抛出 IllegalMonitorStateException
。
但是直接回答你的问题:正在使用的 Condition
的实现是由 Lock#newCondition()
返回的实现。你不需要关心返回的确切类型,因为那是一个实现细节。以下是一些相关概念:
如果你真的想知道使用的 Condition
实现是什么,你可以查看源代码1。目前,ReentrantLock
类使用的是 ConditionObject
的实例。
1. 警告:java.util.concurrent.locks
类的实现是复杂的,涉及并发的复杂性。但是确定使用的 Condition
实现不应该太困难。
英文:
Your understanding of the Javadoc is slightly incorrect. Here's the section of Condition#await()
's Javadoc that you're focusing on:
>### Implementation Considerations
>
>The current thread is assumed to hold the lock associated with this Condition
when this method is called. It is up to the implementation to determine if this is the case and if not, how to respond. Typically, an exception will be thrown (such as IllegalMonitorStateException
) and the implementation must document that fact.
This is saying three things:
- The current thread must hold the lock when calling
await()
. This is further supported by the preceding documentation and the documentation ofLock#newCondition()
:
> Before waiting on the condition the lock must be held by the current thread.
- It is the responsibility of the
Condition
implementation to determine if the current thread holds the lock. - If the current thread does not hold the lock then what should happen is left unspecified.
- It then goes on to say that a typical implementation will throw an
IllegalMonitorStateException
in such cases and that whatever approach is chosen must be documented by the implementation.
Nowhere does it say that the user must supply an implementation of Condition#await()
. All it says is that the developer of a Lock
, and by extension Condition
, implementation must write the code to fit the contract, and provide the necessary documentation.
You mention ReentrantLock
, which is a full implementation of Lock
, so let's focus on that class. Here's an excerpt from the documentation of ReentrantLock#newCondition()
:
>* If this lock is not held when any of the Condition
waiting or signalling methods are called, then an IllegalMonitorStateException
is thrown.
This addresses point three above. This documentation states that the returned Condition
instance will throw an IllegalMonitorStateException
when await()
(and each related method) is invoked by a thread which does not hold the lock.
But to answer your question directly: The implementation of Condition
that's being used is whatever implementation is returned by Lock#newCondition()
. You're not supposed to care about what exact type is returned as that's an implementation detail. Here's some related concepts:
- Programming to an interface
- Factory methods
Lock#newCondition()
is a factory method.
If you really want to know which implementation of Condition
is used you can always look at the source code<sup>1</sup>. The ReentrantLock
class currently uses instances of ConditionObject
.
<sup>1. Warning: The implementations of the java.util.concurrent.locks
classes are non-trivial and deal with the intricacies of concurrency. But determining the implementation of Condition
used should not be too difficult.</sup>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论