基于哪种实现,await 和 signalAll 起作用。

huangapple go评论99阅读模式
英文:

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),并且实现必须记录此事实。

这段话表达了三个要点:

  1. 当调用 await() 时,当前线程必须持有锁。这在前面的文档以及 Lock#newCondition() 的文档中有进一步的支持:

在等待条件之前,当前线程必须持有锁。

  1. Condition 的实现负责确定当前线程是否持有锁。
  2. 如果当前线程 持有锁,则未指定应该发生什么。
    • 接下来还提到,典型的实现会在这种情况下抛出 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:

  1. The current thread must hold the lock when calling await(). This is further supported by the preceding documentation and the documentation of Lock#newCondition():

> Before waiting on the condition the lock must be held by the current thread.

  1. It is the responsibility of the Condition implementation to determine if the current thread holds the lock.
  2. 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:

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>

huangapple
  • 本文由 发表于 2020年4月7日 01:43:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/61065740.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定