Fix #53: Konfigurations-Oeffnen ueber Single-Thread-Executor serialisieren
Statt fuer jede openConfigurationFile-Anfrage einen neuen Thread zu starten, werden Anfragen jetzt ueber einen Single-Thread-ExecutorService mit Daemon-ThreadFactory eingereiht. Mehrfaches Klicken auf Oeffnen erzeugt keine konkurrierenden Worker-Threads mehr; Anfragen werden seriell hintereinander abgearbeitet. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+20
-4
@@ -8,6 +8,8 @@ import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.prefs.Preferences;
|
||||
@@ -169,6 +171,20 @@ public final class GuiConfigurationEditorWorkspace {
|
||||
|
||||
private final GuiConfigurationFileLoader configurationFileLoader;
|
||||
private final GuiConfigurationFileWriter configurationFileWriter;
|
||||
|
||||
/**
|
||||
* Serialisiert Lade-Auftraege fuer Konfigurationsdateien, sodass mehrere schnell
|
||||
* aufeinanderfolgende Oeffnen-Aktionen (z.B. Doppelklick) keine konkurrierenden
|
||||
* Worker-Threads erzeugen. Der Executor ist einzel-threadig: Auftraege werden der
|
||||
* Reihe nach abgearbeitet. Der zugrundeliegende Thread ist als Daemon konfiguriert,
|
||||
* damit die JVM beim Beenden nicht blockiert wird.
|
||||
*/
|
||||
private final ExecutorService configLoaderExecutor = Executors.newSingleThreadExecutor(runnable -> {
|
||||
Thread thread = new Thread(runnable, "gui-config-loader");
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
});
|
||||
|
||||
/**
|
||||
* The current editor state. Package-private to allow direct state injection in smoke tests
|
||||
* that need to set a specific dirty state without going through the full load/save pipeline.
|
||||
@@ -871,7 +887,9 @@ public final class GuiConfigurationEditorWorkspace {
|
||||
return;
|
||||
}
|
||||
|
||||
Thread worker = new Thread(() -> {
|
||||
// Lade-Auftrag wird seriell ueber den Single-Thread-Executor eingereicht, um
|
||||
// Race Conditions durch gleichzeitig laufende Lade-Threads zu vermeiden.
|
||||
configLoaderExecutor.submit(() -> {
|
||||
try {
|
||||
GuiConfigurationEditorState loadedState = configurationFileLoader.load(configFilePath);
|
||||
// Speichern des Pfads als letzte geladene Konfiguration
|
||||
@@ -881,9 +899,7 @@ public final class GuiConfigurationEditorWorkspace {
|
||||
Platform.runLater(() -> showError("Konfiguration konnte nicht geladen werden: "
|
||||
+ safeMessage(exception)));
|
||||
}
|
||||
}, "gui-config-loader");
|
||||
worker.setDaemon(true);
|
||||
worker.start();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user