How to differentiate when wait(long timeout) exit

2020-02-08 23:36发布

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
            }

7条回答
beautiful°
2楼-- · 2020-02-09 00:15

You should use not wait/notify approach.

Will be better to use Lock with Condidions https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Condition.html#await-long-java.util.concurrent.TimeUnit-

It has await with timeout and will return false if the waiting time detectably elapsed before return from the method, else true

查看更多
Ridiculous、
3楼-- · 2020-02-09 00:27

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.

查看更多
狗以群分
4楼-- · 2020-02-09 00:27

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

查看更多
爷的心禁止访问
5楼-- · 2020-02-09 00:32

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.

查看更多
疯言疯语
6楼-- · 2020-02-09 00:33

Don't use System.currentTimeMillis(), use System.nanoTime() instead.

The first one meassures absolute time (based on system clock) and might have curious results if the system time is changed. For example: A 5 second wait can have a duration of an hour if the clock is moved backward by an hour, or a 10 minute wait will be done after 0 seconds if the clock is moved foreward.

The second one meassures relative time. It will always run in one direction at constant speed, but it has no origin. That means that the values can only be used to meassure relative time, but can and should not be used to determine a date.

查看更多
劫难
7楼-- · 2020-02-09 00:35

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.

查看更多
登录 后发表回答