Ich habe ein Java-Thread so etwas wie dies funktioniert:Java-Thread aufwacht spontan
while (running) {
synchronized (lock) {
if (nextVal == null) {
try {
lock.wait();
} catch (InterruptedException ie) {
continue;
}
}
val = nextVal;
nextVal = null;
}
...do stuff with 'val'...
}
An anderer Stelle habe ich den Wert wie folgt aus:
if (val == null) {
LOG.error("null value");
} else {
synchronized (lock) {
nextVal = newVal;
lock.notify();
}
}
Gelegentlich (buchstäblich einmal alle paar Millionen mal) nextVal wird auf null gesetzt. Ich habe in Log-Meldungen geworfen, und ich kann sehen, dass die Reihenfolge der Ausführung wie folgt aussieht:
- Thread1 NEXTVAL zu newVal setzt
- Thread1 lock.notify() aufruft
- Thread2 von Schloss aufwacht. (warten)
- Thread2 val zu NEXTVAL setzt
- Thread2 NEXTVAL setzt
- auf null Thread2 Sachen tut mit val
- Thread2 lock.wait() aufruft
- Thread2 von lock.wait aufwacht()
- kein anderer Thread aufgerufen lock.notify() und Thread2 nicht unterbrochen worden
- Thread2 setzt val zu NEXTVAL (die null ist) hat
- usw.
ich explizit überprüft haben und die Sperre wird ein zweites Mal aufwacht, ist es nicht unterbrochen wird.
Mache ich hier etwas falsch?
+1 für eine gut geschriebene Erklärung, aber -1 für das Lesen der Javadoc nicht sorgfältiger :-) –
IIRC, es gibt keine Garantie, dass ein Thread nicht von einer Wartezeit aufgeweckt wird, während die Wartebedingung noch nicht erfüllt ist. Sie müssen die Bedingung immer überprüfen und die Wartezeit erneut ausführen, wenn sie nicht erfüllt ist. –
(Der Grund dafür hat mit der Komplexität der Implementierung der "Weck" -Logik zu tun. Das garantieren, dass es nie ein unechtes Wecken gibt, ist ohne eine teure Synchronisation fast unmöglich.) –