Ich habe ein paar Fragen zu Platform.runLater
. Ich habe eine JavaFX-Anwendungsklasse. In dieser Klasse führe ich einen Thread aus (Der Thread liest Daten von einem Netzwerk-Socket).
Wenn ich jetzt ein neues Stage
innerhalb des Threads anlege, gibt das System eine Ausnahme aus (JavaFX Event-Dispatcher-Thread und mein Netzwerk-Lese-Thread sind nicht identisch) - ich verstehe dieses Verhalten.
Aber die andere Seite ist, ich füge den Text vom Netzwerkleser an ein existierendes TextArea
an oder füge einige Elemente in einem ListView<String>
hinzu oder entferne - das wirft keine Ausnahme - warum? Ich dachte, dass JavaFX ein Singlethread ist (Der ui-Bibliotheksteil). Ist das das Gleiche wie in Swing: Manchmal klappt es und manchmal hast du einfach Müll (; wegen EDT)?
Meine Fragen:
Platform.runLater
mit einer run()
-Methode zu verwenden? In Kombination mit einem try catch (oder multiple catch) sieht es sehr seltsam aus
Ich weiß, dass die Verwendung von Platform.runLater
in einem Thread nicht so gut ist (Design-Lösung)
"das wirft keine Ausnahme - warum?" weil nicht alle solchen Fälle geholt werden ... Möglicherweise, wegen der Leistungsüberlegungen, möglicherweise, ist es nur eine verpasste Funktionalität.
Alle Interaktionen mit JavaFX-Objekten (einschließlich der Erstellung) müssen im JFX-Thread ausgeführt werden. Wenn Sie auf diese JFX-Objekte von einem anderen Thread aus zugreifen möchten, verwenden Sie die Methoden runLater oder runAndWait. Wenn es jetzt keine Ausnahme auslöst, wird es möglicherweise in Zukunft Ausnahmen auslösen. Jede Interaktion mit dem JFX-Objekt kann zu Folgeaktionen und -ereignissen führen, die von einem Thread-Checker übernommen werden - Sie können nicht sicher sein.
Ich glaube nicht, dass es eine gute Dokumentation darüber gibt - nur eine einfache Regel - benutze runLater oder runAndWait.
Kürzere und sauberere Methode - wird in JDK 8 mit Lambda bereitgestellt.
Alexanders Antwort fängt die wichtigsten Punkte bezüglich Ihrer Fragen ein.
Diese Antwort enthält einige zusätzliche Informationen.
Wann löst der JavaFX-Event-Dispatcher-Thread eine Ausnahme aus und wann nicht?
Das JavaFX-System prüft nicht immer, ob Zugriffe auf Objekte, die das aktive Szenegraph beeinflussen, ordnungsgemäß auf den JavaFX-Thread beschränkt sind. Letztlich liegt die Verantwortung für die Thread-Sicherheit beim JavaFX-Anwendungsprogrammierer - nicht beim JavaFX-System. Sie müssen sehr vorsichtig sein, wenn Sie Multi-Threaded-Programmierung in JavaFX durchführen, andernfalls kann das Verhalten der Anwendung fehlschlagen oder unvorhersehbar werden.
Sind irgendwelche guten Dokumente darüber
Probieren Sie das JavaFX-Tutorial: Parallelität in JavaFX .
Gibt es einen einfacheren (kürzeren und saubereren) Weg, Platform.runLater mit einer run () Methode zu benutzen?
Nein. Platform.runLater
ist so einfach wie es geht.
Als beiseite. . .
Aufgabe und Service
Erwägen Sie, die Aufgabe oder Service Unterklassen von Arbeiter . Dies sind JavaFX-Wrapper für FutureTask (was wiederum ein Runnable ). Die Mitarbeiter stellen eine Aufruf -Methode bereit, um die Logik auf einem auszuführen Hintergrundfaden. Sie behalten die Ausführung Status bei (mit Thread-sicherer Callback-Benachrichtigung für den JavaFX-Thread für Statusänderungen) und gibt die Ergebnisse des Aufrufs über value ,
Nutzen Sie die Entwurfsmuster in den Beispielen Task
und Service
javadoc, um die Erstellung threadsicherer Anwendungen mit Funktionen wie:
A Worker
ist komplementär zu Platform.runLater
. Verwenden Sie Platform.runLater
, wenn Sie den JavaFX-Anwendungs-Thread ausführen und eine Logik für den JavaFX-Anwendungs-Thread ausführen möchten. Verwenden Sie Worker
, wenn Sie den JavaFX-Anwendungs-Thread ausführen und eine Logik oder (insbesondere) E / A in einem neuen Thread generieren möchten, damit Sie den JavaFX-Anwendungs-Thread nicht blockieren. Sie würden niemals Netzwerk-I / O in der Platform.runLater
-Methode von run
durchführen wollen, aber oft möchten Sie dies in% Worker
-Methode tun.
Auch die Verwendung von call
und Task
ist nicht inkompatibel mit der Verwendung von Service
. Wenn Sie zum Beispiel sehr lange Platform.runLater
ausführen, von denen Sie regelmäßig Teilergebnisse an die Benutzeroberfläche zurückgeben möchten oder wenn ein Puffer gefüllt ist, können Sie Task
in der Methode Platform.runLater
der Aufgabe ausführen.
Workers sind hilfreich, wenn Sie nicht über einen vorhandenen Thread-Dienst verfügen, der von einer Bibliothek bereitgestellt wird, sondern stattdessen eigene Threads erstellen, die im Hintergrund ausgeführt werden. Wenn Sie einen vorhandenen Thread-Dienst haben, müssen Sie call
verwenden, um Logik für den JavaFX-Anwendungsthread auszuführen.
Beachten Sie, dass Sie immer noch wissen müssen, was Sie tun, auch wenn Sie Platform.runLater
verwenden. Sie müssen dennoch darauf achten, dass Sie nicht die standardmäßigen JavaFX-Regeln für den gemeinsamen Zugriff verletzen, z. B. niemals Knoten im aktiven Szenendiagramm aktualisieren (einschließlich der Aktualisierung von Werten, an die Knoten im aktiven Szenegraph gebunden sind). Beispiele sind die beobachtbare Liste von Elemente , die ein ListView ).
Tags und Links java multithreading javafx-2 event-dispatch-thread