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.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
@@ -169,6 +171,20 @@ public final class GuiConfigurationEditorWorkspace {
|
|||||||
|
|
||||||
private final GuiConfigurationFileLoader configurationFileLoader;
|
private final GuiConfigurationFileLoader configurationFileLoader;
|
||||||
private final GuiConfigurationFileWriter configurationFileWriter;
|
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
|
* 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.
|
* 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;
|
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 {
|
try {
|
||||||
GuiConfigurationEditorState loadedState = configurationFileLoader.load(configFilePath);
|
GuiConfigurationEditorState loadedState = configurationFileLoader.load(configFilePath);
|
||||||
// Speichern des Pfads als letzte geladene Konfiguration
|
// Speichern des Pfads als letzte geladene Konfiguration
|
||||||
@@ -881,9 +899,7 @@ public final class GuiConfigurationEditorWorkspace {
|
|||||||
Platform.runLater(() -> showError("Konfiguration konnte nicht geladen werden: "
|
Platform.runLater(() -> showError("Konfiguration konnte nicht geladen werden: "
|
||||||
+ safeMessage(exception)));
|
+ safeMessage(exception)));
|
||||||
}
|
}
|
||||||
}, "gui-config-loader");
|
});
|
||||||
worker.setDaemon(true);
|
|
||||||
worker.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user