Reputation: 953
According to the documentation for ReentrantLock.newCondition(), the calling thread needs to own a lock before calling a signaling method:
If this lock is not held when any of the Condition waiting or signalling methods are called, then an IllegalMonitorStateException is thrown.
Indeed, this is what I see when I try it:
java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signalAll(AbstractQueuedSynchronizer.java:1954)
at PingPongPrinter_.printPing(PingPong2.java:35)
at WorkerPing.run(PingPong2.java:53)
at java.lang.Thread.run(Thread.java:748)
So why do this restriction exists in java.util.concurrent.locks.ReentrantLock
? I believe there is no such restriction in C++.
Upvotes: 0
Views: 82
Reputation: 551
Answer to original question
You're unlocking a lock associated with the condition before signaling it. From documentation:
An implementation may (and typically does) require that the current thread hold the lock associated with this Condition when this method is called. Implementations must document this precondition and any actions taken if the lock is not held. Typically, an exception such as IllegalMonitorStateException will be thrown.
Also, only lock for the time required to modify the value you are conditioning for.
void printPong() throws Exception {
// wait for pong condition
while (isPing) {
blockPong.await();
}
rlock.lock();
isPing = true; // modify value
blockPing.signalAll(); // signal ping
rlock.unlock();
System.out.println("Pong");
}
void printPing() throws Exception {
// wait for ping condition
while (!isPing) {
blockPing.await();
}
rlock.lock();
isPing = false; // modify value
blockPong.signalAll(); // signal pong
rlock.unlock();
System.out.println("Ping");
}
Answer to modified question
So why do this restriction exists in java.util.concurrent.locks.ReentrantLock? I believe there is no such restriction in C++.
Because ReentrantLock
is mutually exclusive. It provides access to one single thread at any given time. That's a design choice.
In C++ the std::condition_variable
also requires you to own a mutex to the resource in order to signal.
Upvotes: 1