Dies ist das in der Klasse Task
verwendete Idiom zur Implementierung der updateMessage(...)
-Methode und anderer ähnlicher Methoden. Es bietet eine schöne, robuste Lösung, die den FX Anwendung Faden zu vermeiden Überschwemmungen:
import java.util.concurrent.atomic.AtomicLong;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ThrottlingCounter extends Application {
@Override
public void start(Stage primaryStage) {
final AtomicLong counter = new AtomicLong(-1);
final Label label = new Label();
final Thread countThread = new Thread(new Runnable() {
@Override
public void run() {
long count = 0 ;
while (true) {
count++ ;
if (counter.getAndSet(count) == -1) {
updateUI(counter, label);
}
}
}
});
countThread.setDaemon(true);
countThread.start();
VBox root = new VBox();
root.getChildren().add(label);
root.setPadding(new Insets(5));
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 150, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
private void updateUI(final AtomicLong counter,
final Label label) {
Platform.runLater(new Runnable() {
@Override
public void run() {
final String msg = String.format("Count: %,d", counter.getAndSet(-1));
label.setText(msg);
}
});
}
public static void main(String[] args) {
launch(args);
}
}
Die AtomicLong
hält den aktuellen Wert verwendet werden, um das Etikett zu aktualisieren. Die Zählung erhöht und aktualisiert die AtomicLong
fortlaufend, plant jedoch nur einen Anruf an Platform.runLater(...)
, wenn der aktuelle Wert -1 ist. Die Platform.runLater(...)
aktualisiert die Label
mit dem aktuellen Wert aus den AtomicLong
und dreht die AtomicLong
auf -1 zurück, was darauf hinweist, dass es für ein neues Update bereit ist.
Die hier Wirkung ist es, neue Anrufe zu Platform.runLater(...)
planen, wenn der FX Anwendung Faden bereit ist, sie zu handhaben. Es gibt kein fest codiertes Zeitintervall, das optimiert werden müsste.
Warum nicht die Atomic wird auf „-1“ (was die gui ist bereit, zu aktualisieren), nachdem das Etikett in der platform.runlater-runnable eingestellt wurde? – user3607022
@ user3607022 Sie müssen den aktuellen Wert abrufen und den Wert atomisch auf "-1" * setzen. Wenn Sie den Wert für die Anzeige abgerufen haben und ihn nach der Anzeige auf "-1" setzen, ist es möglich, dass der andere Thread den Wert erneut zwischen diesen beiden Werten festlegt: 1. Der UI-Thread ruft den Wert ab. 2. Hintergrund-Thread-Aktualisierungen Da der Wert '! = - 1 'ist, wird keine Aktualisierung geplant, 3. ui setzt den Wert auf -1. In diesem Szenario könnten Sie diesen Zwischenwert "verpassen"; Wenn es das Letzte wäre, was der Thread getan hätte, würden Sie ihn dauerhaft vermissen. –
Gibt es eine einfache Möglichkeit, genau zu beschreiben, welche Updates gelöscht werden? – user3607022