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?!
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 asIllegalMonitorStateException
) 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 of Lock#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.
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 anIllegalMonitorStateException
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:
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 code1. The ReentrantLock
class currently uses instances of ConditionObject
.
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.