0

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 awaiting 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 awaiting 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 awaiting 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?

Erik
  • 4,305
  • 3
  • 36
  • 54
  • It doesn't make sense to signal if we don't know that the precondition has been met (in your example `ok_to_continue`). Conversely, it doesn't make sense to hold a lock if we're not executing code that relies on it. In both cases we don't really know the state, but I think the default assumption is different. – shmosel Feb 16 '17 at 21:39
  • Ah, that makes sense. The `ok_to_continue` expression may indeed throw an exception, thus making the condition uncertain. However, while the *thread unsafe business* we were about to execute now isn't going to be executed anymore, in some cases we might want to ensure another thread `await`ing the condition will be `signal`led, hence my question remains. Besides, we could add a `catch` clausule for the `ok_to_continue` expression (as well as for the *thread unsafe business*). Is that the recommended approach, catching exceptions if you expect `signal` or `signalAll` may not be called? – Erik Feb 16 '17 at 22:44

0 Answers0