2016-04-01 7 views
1

Ich habe gelernt, dass beim Warten auf ein Objekt, die Bedingung in einer Schleife statt innerhalb einer einzigen if condition platziert werden sollte. Ein Grund dafür ist, dass verschiedene falsche Weckaufrufe vermieden werden.Java-gleichzeitige - unerwünschte Wakeups und warten (Timeout)

Zum Beispiel:

synchronized (obj) { 
    while (condition is false) { 
     obj.wait(5 * 1000); 
    } 
    ... do something ... 
} 

Ich mag jedoch nur 5 Sekunden warten, bis der Faden informiert werden. Im obigen Code wartet der Thread 5 Sekunden. Aber nach dieser Zeit, wenn die Bedingung immer noch falsch ist, warten wir erneut. Dies wäre nicht der Fall sein, wenn ich folgendes hatte:

synchronized (obj) { 
    if (condition is false) { 
     obj.wait(5 * 1000); 
    } 
    ... do something ... 
} 

Dies widerspricht aber der Leitlinie wir eine Schleife anstelle eines einzelnen, wenn die Bedingung verwenden sollten!

Wie ist das gelöst?

+2

Sie vor dem Eintritt in die Schleife aktuelle Zeit erinnern kann, und die Bedingung wahr machen, wenn Zeitraum gegeben beim Aufwachen verstrichen. –

+0

Doh, natürlich. Gute Idee! –

+0

Ich beantwortete meine eigene Frage. Hoffentlich ist es richtig. –

Antwort

2

hier ist, wie ich dies in der Regel handhaben:

long timeout = ....; 
synchronized(obj) { 
    long start = System.currentTimeMillis(); 
    while(!condition && (timeout > 0)) { 
    obj.wait(timeout); 
    long now = System.currentTimeMillis(); 
    timeout -= (now - start); 
    start = now; 
    } 
} 
1

meine eigene Frage zu beantworten, könnte dies funktionieren:

synchronized (obj) { 
    for (long time = System.currentTimeMillis() + timeout; !condition && System.currentTimeMillis() < time;) { 
     obj.wait(time - System.currentTimeMillis()); 
    } 
    if (condition) { 
     ... do something ... 
    } 
} 
Verwandte Themen