When using a Lock
with a Condition
, e.g.,
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
and locking, i.e.,
lock.lock();
then while it is not ok to continue, e.g.,
try {
while (!ok_to_continue) {
we await
the condition
:
condition.await();
}
Then, typically, after we're done with our thread unsafe business, any or all await
ing threads are signalled using signal
or signalAll
in the try
block, i.e.,
condition.signalAll();
before ensuring the lock is unlocked, i.e.:
} finally {
lock.unlock();
}
By typically I mean: as recommended by programming teachers, Java books[1] and Oracle[2] the signal
and signalAll
method are called in the try
block. As per Oracle's documentation, these methods are typically called while the corresponding Lock
is held by the current thread. Does this mean the signal
and signalAll
methods can also be called in the finally
block instead of before? Why is it typical to signal await
ing threads from within the try
block, where an exception may be thrown by the thread unsafe business? In other words, we can't be sure the signal
or signalAll
methods are called at all, am I correct? Why then is it not typical to ensure they are called by calling them in the finally
block? That is:
} finally {
condition.signalAll();
lock.unlock();
}
By calling one of them in the finally
block, we ensure an await
ing thread is activated and a deadlock could be prevented.
What are uses of either construct and why would Oracle use the condition in the try
block instead of in the finally
block?