Java Monitors: How to know if wait(long timeout) ended by timeout or by Notify()?

MountainX picture MountainX · May 24, 2011 · Viewed 8.7k times · Source

First, this is a near duplicate of: How to differentiate when wait(long timeout) exit for notify or timeout?

But it is a new follow-on question.

Having this wait declaration:

public final native void wait(long timeout) throws InterruptedException;

It could exit by InterruptedException, or by timeout, or because Notify/NotifyAll method was called in another thread, Exception is easy to catch but...

My code absolutely needs to know if the exit was from timeout or notify. (In the future, this code needs to be redesigned, but that cannot be done now. So I need to know the reason for the exit from wait.)

Specifically, can someone give an example of using a ThreadLocal Boolean that is set to true only on notify() and where all this is inside an existing loop as shown below? (This was more or less the accepted answer in the other thread, but no specific code example was given. I'm not all that familiar with Java, so I need a specific code example -- ideally in the context of the existing code below.)

public synchronized int getLastSequenceNumber() {
    while (empty) {
        try {
            wait(waitTimeValue);
        } catch (InterruptedException e) {}
    }
    empty = true;
    return reportedSequenceNumber;
}
public synchronized void reconcileLastSequenceNumber(int sequenceNumber) {
    empty = false;
    this.reportedSequenceNumber = sequenceNumber;
    notifyAll();
}

the Boolean "empty" serves a purpose outside of the specific question I'm asking here. I believe I will need to add another Boolean to fulfill the suggested answer from the original question. How would I integrate that proposed solution into the existing code snippet above? Thanks.

Answer

finnw picture finnw · May 24, 2011

You might be better off using a Condition (and its await method) rather than built-in monitors, because await returns a boolean value indicating whether the wait timed out.

And even then, you must beware of spurious wakeup (which is indistinguishable from a call to signal.)