Java:如何在wait()中区分虚假唤醒和超时

M S*_*M S 9 java multithreading wait

这是线程正在等待notify()或超时的情况.这里添加了一个while循环来处理虚假唤醒.

boolean dosleep = true;
while (dosleep){
    try {
        wait(2000);
        /**
         * Write some code here so that
         * if it is spurious wakeup, go back and sleep.
         * or if it is timeout, get out of the loop. 
         */

    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我如何区分虚假唤醒和超时?如果它是一个虚假的醒来,我需要回去等待.如果是超时,我需要退出循环.

我可以很容易地识别notify()的情况,因为我将在notify()调用时将dosleep变量设置为false.

编辑:由于嵌入式项目的要求,我使用的是1.4版java.我不能使用,Condition因为它只在1.5后可用.

提前致谢.

Cam*_*ner 8

你可以这样做:

boolean dosleep = true;
long endTime = System.currentTimeMillis() + 2000;
while (dosleep) {
    try {
        long sleepTime = endTime - System.currentTimeMillis();
        if (sleepTime <= 0) {
            dosleep = false;
            } else {
            wait(sleepTime);
        }
    } catch ...
}
Run Code Online (Sandbox Code Playgroud)

这应该在Java 1.4中正常工作,它将确保您的线程至少睡眠2000毫秒.


den*_*nko 5

在这种情况下,我相信Locks 并且Condition会更好地满足您的需求。请检查 javadocs Condition.awaitUntil()- 它有一个使用示例


Bri*_*128 5

如果要区分这两种情况,则需要跟踪超时。

long timeout = 2000;
long timeoutExpires = System.currentTimeMillis() + timeout;
while(dosleep) {
  wait(timeout);
  if(System.currentTimeMillis() >= timeoutExpires) {
    // Get out of loop
    break;
  }
}
Run Code Online (Sandbox Code Playgroud)

也就是说,丹尼斯建议使用Condition该类是执行此操作的更好方法。

  • 不要使用System.currentTimeMillis()来使用某种形式的单调时间,因为当更改系统时钟时,这很容易出现异常。http://stackoverflow.com/questions/351565/system-currenttimemillis-vs-system-nanotime (2认同)