Hier ist ein Ausschnitt aus einem Web-Server, die ich zur Zeit bin Gebäude ...Peculiar Verhalten mit mehreren Threads/volatile Variablen/conditionals/Schleifen (Java)
// ...
threadPool = Executors.newCachedThreadPool(); while (true) if(this.isOn) { try { // listen for incoming connection this.clientSocket = serverSocket.accept(); } catch (IOException e) { System.err.println("LOG: >> Accept failed! "); System.exit(1); } // as soon as a connection is established send the socket // with a handler/processor to the thread pool for execution threadPool.execute(new ClientRequestProcessor(clientSocket)); }
// ...
Bitte beachten Sie, dass die isOn Variable ein VOLATILE boolean ist.
Wenn ich das in eine Weile mache ... funktioniert dieser Code ... aber so wie es ist, tut es nicht. Darf ich fragen warum? Aus logischer Sicht sollten beide funktionieren, auch wenn ich diese Flagge in einem if teste ... verpasse ich etwas ?!
[Spätere Bearbeitung:] Durch die nicht funktioniert meine ich ... ein Browser (z. B. Firefox) kann nicht verbinden, tatsächlich versucht es, aber Timeout schließlich. Wenn ich das in eine Weile (isOn) ändere, funktioniert es wie ein Zauber.
Alle Vorschläge/Ideen sind mehr als willkommen !!!
P.S. Ich brauche diese Kombination "while (true) if/while (Testflag) {...}" weil der Server von einer GUI aus gestartet/gestoppt werden kann ... also die oberste Ebene while (true) wird benötigt, damit ich kann überprüfen, ob ich eingeschaltet bin (und damit auf Verbindungen höre) oder ob ich ausgeschaltet bin (und sich nicht wirklich um eingehende Verbindungen kümmern). Die Event-Handler der GUI können die Flagge jederzeit ändern.
Ich stimme völlig mit dem überein, was Sie gesagt haben. Außerdem haben Sie recht, wenn Sie das Flag auf "false" setzen, um sicherzustellen, dass ein anderes "auf eine Verbindung wartet", bevor der Server tatsächlich "nicht mehr bedient". Aber das erklärt immer noch nicht das unberechenbare Verhalten, das ich mit der aktuellen Version des Codes bekomme! Ich werde wahrscheinlich Ihre Lösung übernehmen, aber ich bin immer noch kurios, warum eine Version funktioniert und die andere nicht ... wenn logisch beide sollten. Die Frage war nicht wirklich, ob es eine bessere Lösung gibt (du hast es bereits bewiesen!), Aber warum verhält sich dieser Java-Code so unbeholfen? – Tibbers
@Tibi, while (true) if (flag) und while (true) while (flag) sollte in Ihrem Fall identisch sein. Ich vermute, dass Ihr Test nicht stabil reproduzierbar ist. –
Auch hier könntest du recht haben. Denn wenn ich die if-Variante mit dem Debugger starte und den Code Zeile für Zeile ausfühle funktioniert es einwandfrei ... aber wenn ich nur auf run klicke und es in Ruhe lasse funktioniert die if-Variante nicht! In der Tat kann ich den tatsächlichen Zustand der Maschine wahrscheinlich nicht reproduzieren, was jeden Versuch, dieses unbeholfene Verhalten zu verstehen, nutzlos macht. Wie auch immer, danke für die schnellen Antworten ... Ihr (erstes) Refactoring/Redesign-Angebot wurde bereits umgesetzt und wirkt wie ein Zauber! – Tibbers