Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:如何区分虚假唤醒和等待超时()_Java_Multithreading_Wait - Fatal编程技术网

Java:如何区分虚假唤醒和等待超时()

Java:如何区分虚假唤醒和等待超时(),java,multithreading,wait,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

这里是一个线程正在等待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();
    }
}
在这种情况下,我如何区分虚假唤醒和超时?如果这是一个虚假的醒来,我需要回去等待。如果是超时,我需要退出循环

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


编辑:由于嵌入式项目的要求,我使用的是1.4Java版本。我不能使用
条件
,因为它仅在1.5版本后可用


提前谢谢

我相信在这种情况下,
Lock
s和
Condition
更适合您的需要。请检查javadocs的
条件。waituntil()
-它有一个用法示例

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

long timeout = 2000;
long timeoutExpires = System.currentTimeMillis() + timeout;
while(dosleep) {
  wait(timeout);
  if(System.currentTimeMillis() >= timeoutExpires) {
    // Get out of loop
    break;
  }
}
也就是说,denis建议使用
条件
类是更好的方法。

您可以这样做:

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 ...
}
boolean dosleep=true;
long-endTime=System.currentTimeMillis()+2000;
while(dosleep){
试一试{
long sleepTime=endTime-System.currentTimeMillis();

如果(睡眠时间)由于嵌入式项目的要求,我使用的是1.4 java版本。我担心只有1.5版本后的情况才可用。Bringer128有一个合理的解决方案,但是,我质疑您为什么要这样做。中断通常不是“虚假唤醒”,而是中断和停止进程的信号。这与中断无关“虚假唤醒”可以在任何时候出现。如果它在我进入wait()后的同一时间出现,那么我不想退出循环。我需要在退出循环之前确定我等待了至少
timeout
时间。我看到了。你没有被中断,但是其他线程正在调用notify(),或者更可能的是,调用notifyAll(),您会被唤醒。请参见,此代码在伪唤醒发生后再次等待整个超时,但这是不正确的。Cameron Skinner的响应是正确的,并且与JDK v4向后兼容(而Denis.Solonenko的回答也是正确的,它使用
java.concurrency
API,因此需要JDK v5+)。这是我的话题。不要使用System。currentTimeMillis()使用某种形式的单调时间,因为当系统时钟改变时,这很容易出现错误。正如Jiri Patera所指出的,该示例本身是有缺陷的。此外,除了“Condition类“实际上,作为一个接口,的JavaDoc明确表示,
实现可以自由地消除虚假唤醒的可能性,但建议应用程序程序员始终假设它们可以发生,因此总是在循环中等待。Cameron Skinner有唯一正确的答案。