views:

133

answers:

5

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...

There is any way to know if the exits cause was timeout or notify?

EDIT:

This is a tricky way that could work, (although I don't like it)

          long tBefore=System.currentTimeMillis();
          wait(TIMEOUT);
          if ((System.currentTimeMillis() - tBefore) > TIMEOUT) 
            { 
               //timeout
            }
+2  A: 

You can't differentiate between the two unless you provide some additional code. For example by adding a ThreadLocal Boolean that is set to true only on notify()

But first you must make sure your logic requires this differentiation.

Bozho
The OP already knew an exception wouldn't be thrown and wants to distinguish between a timeout and a notify. This does not provide any useful information to that end.
Mark Peters
thanks, I misunderstood the OP. Updated now.
Bozho
+1 for rewrite, and yes a boolean an a synchronized method is what I am using now
Hernán Eche
A: 

Exception is not thrown on notify and time out.

I think it's better to rely on java.lang.concurrent package synchronisation objects instead of using Object.wait().

Manuel Selva
I'll do some research on that
Hernán Eche
+3  A: 

This doesn't exactly answer the question, but it will probably solve your problem: Use higher level concurrency mechanisms. Wait/notify is usually more low-level than you'd want, for this reason among many others.

For example, if you were using BlockingQueue.poll(long, TimeUnit), you could check if the result is null to know if you timed out.

Mark Peters
mmm I'll do some research on that too.. damn wait() all I ask him is to return a boolean!
Hernán Eche
+6  A: 

There is one more reason that notify can return: spurious wakeup. This is an unlikely but possible thing, because preventing spurious wakeups is very expensive on some hardware/OS combinations.

Because of this you always have to call wait() in a loop and re-check the condition that you are waiting for. During this work it's easy to check for timeout at the same time.

For details I recommend the book "Java Concurrency In Practice". And using higher level constructs that will get this all correct for you.

Darron
+1 I will have in account those spurious wakeup
Hernán Eche
+1  A: 

There's no way to tell directly - that is, you would have to add additional code to determine this. Often when you wait(), you're waiting for something to happen which changes the state of an object in some way - e.g. by setting a boolean variable, perhaps. If that's the case, then you may be able to simply check the state of that variable to see if the event occurred, or you merely timed out. Or you can look at the value of System.currentTimeMillis() to see i the elapsed time is greater than or equal to the timeout period - if it is, that would be a clue you have probably timed out (though it's not an absolute guarantee). Or if the elapsed time is less than the timeout period then you certainly have not timed out. Does that help?

YoK
I am actually using currentTimeMillis(), but I was wondering if there was some better way
Hernán Eche
@Hernán Eche As I have put in my answer its not an absolute guarantee. if you can tell , why you want to identify whether it timedout ? We can look for some solution.
YoK
@YoK yes, I know that's not a very good approach, I use it for a loop while(true){wait(timeout); other tasks..; } so it can exit the loop when the wait was really notified, for example if wait would return boolean, it would be something like while(true){if(wait(timeout)) break; other tasks..; } anyway I will encapsulate it all within a class and a flag with synchronized method to wait/notify in parallel with the setting of this flag
Hernán Eche