Java并发-虚假唤醒和等待(超时)
我了解到,当等待一个对象时,条件应该放在循环中,而不是放在单个Java并发-虚假唤醒和等待(超时),java,concurrency,Java,Concurrency,我了解到,当等待一个对象时,条件应该放在循环中,而不是放在单个if condition中。这样做的一个原因是为了避免可能发生的各种虚假唤醒调用 例如: synchronized (obj) { while (condition is false) { obj.wait(5 * 1000); } ... do something ... } 但是,我只想等待5秒钟,等待线程得到通知。在上面的代码中,线程等待5秒钟。但在这段时间之后,如果条件仍然为假,我们将
if condition
中。这样做的一个原因是为了避免可能发生的各种虚假唤醒调用
例如:
synchronized (obj) {
while (condition is false) {
obj.wait(5 * 1000);
}
... do something ...
}
但是,我只想等待5秒钟,等待线程得到通知。在上面的代码中,线程等待5秒钟。但在这段时间之后,如果条件仍然为假,我们将再次等待。如果我具备以下条件,情况就不会如此:
synchronized (obj) {
if (condition is false) {
obj.wait(5 * 1000);
}
... do something ...
}
但这与我们应该使用循环而不是单个if条件的指导方针相矛盾
这是如何解决的?回答我自己的问题,这可能有用:
synchronized (obj) {
for (long time = System.currentTimeMillis() + timeout; !condition && System.currentTimeMillis() < time; ) {
obj.wait(time - System.currentTimeMillis());
}
if (condition) {
... do something ...
}
}
synchronized(obj){
对于(长时间=System.currentTimeMillis()+超时;!条件和System.currentTimeMillis()
我通常是这样处理的:
long timeout = ....;
synchronized(obj) {
long start = System.currentTimeMillis();
while(!condition && (timeout > 0)) {
obj.wait(timeout);
long now = System.currentTimeMillis();
timeout -= (now - start);
start = now;
}
}
您可以在进入循环之前记住当前时间,如果唤醒时经过了给定的时间段,则使条件为真。当然是Doh。好主意!我回答了我自己的问题。希望它是正确的。在散文中,条件仅指布尔值,前提是它可能无限期地等待,直到收到通知为止。超时基本上是第二个条件。@Dave nice,但我建议使用它的
.tryAcquire(时间,时间单位)
。如果只需要暂时阻止当前线程,请使用thread.sleep()