2012-09-25 33 views
0

我有场景:我想等待,直到出现错误。通常需要20秒左右。Java使用Thread.sleep()或继续询问

while(foo) { 
    try { 
     Thread.sleep(5000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

或者只是去这样?

while(foo) { 

} 
+0

你可以得到任何切换foo吗?如果可以,等待/通知似乎是合理的。尽量不要去投票。使用Sleep()会导致延迟并浪费CPU /内存周期,如果没有Sleep(),则会严重浪费CPU /内存周期和。很有可能,总延迟也是如此(如果该框被重载,设置foo的线程可能不会长时间运行)。 –

回答

8

忙于等待20秒并不是一个好主意 - 睡5秒意味着你可能会错过5秒的信号。你能不能用一种不同的方式,如CountdownLatch

CountDownLatch latch = new CountDownLatch(1); 

//code that triggers the signal 
latch.countDown(); 

//code that waits for the signal 
try { 
    latch.await(); 
} catch (InterruptedException e) { 
    //handle interruption 
} 
+0

数字'1'指定了什么? – Jaanus

+1

'latch.await()'将一直等到倒数到达0为止。倒数开始于传递给构造函数的参数(在本例中为1)。每次调用'latch.countdown()'都会减少倒数。例如,如果你写'latch = new CountDownLatch(2);'在latch.await()可以继续执行下一条指令之前,它需要对'latch.countDown()'进行2次调用。 – assylias

2

这只是一个单元测试,我会用第一个例子。它不一定非常漂亮。

如果这是生产代码,您最好使用不同的结构,如条件或未来。

1

第二种形式是要燃烧大量的CPU周期。它会尽可能快地检查,也许每秒钟可以检测十万次。这不是一个好主意。

Thread.sleep()比较好一点。如果foo是非易失性字段和/或不在​​区块中,则此处仍存在其他问题。实际上并不保证它会看到来自另一个线程的更新。

java.util.concurrent中使用原始像CountDownLatch

0

当然,第二种形式不能使用。这可能导致CPU并导致问题。第一种形式更好。

什么会改变价值?

如果它只是另一个线程,那么你可以考虑使用wait/notify或任何并发结构。

0

没有人喜欢等待/通知吗?这个效率比Sleep()循环机制更简单,而且比'CountDownLatch'更少打字,

+1

你仍然需要编写自己的条件变量,并在某种循环中检查它,以区别于虚假唤醒(参见http://stackoverflow.com/questions/1050592/do-spurious-wakeups-actually-发生)CountDownLatch最终会比所有更少的写入,并且意味着你不会错误 - 例如,不会让标志变成volatile或者确保某些内存屏障将信号复制到等待线程的内存。 –