Ich habe wieder ein Mal ein Problem mit Threads. Auf meine JavaFX GUI habe ich einen Button der auf druck Daten aus der DB ausliest. Da die DB relativ lange hat bis die Antwort kommt (>1sek.) habe ich einen separaten Thread für diese Abfrage gemacht:
* Holt die Informationen des gewünschten Artikels aus der Datenbank
*
* @param barcode
*/
public void artikelLaden(String barcode, String artikel) {
Task<Integer> task = new Task<Integer>() {
@Override
protected Integer call() throws Exception {
// Artikel in Datenbank identifizieren
int errCode = verwaltungTray.artikelAufTray(barcode, artikel);
return errCode;
}
};
new Thread(task).start();
}```
Nun kann man jedoch mehrmals hintereinander auf den Button drücken und die abfragen werden alle ausgeführt... Wie kann ich die GUI synchronisieren damit der Event der taste erst ausgeführt ist wenn die DB ihre Daten beisammen hat?
Vielen Dank schonmal
vermutest du, dass es ein fertiges Konstrukt dafür gibt? denkbar, ich kenne es dann nicht
allgemein selber gebaut ist es doch überschaubar,
von normaler Aufrufposition irgendwohin wo es synchronized-Methoden gibt,
darin prüfen ob ein boolean gesetzt ist oder der Thread in einer Variablen gesetzt ist und noch läuft usw.,
was soll denn passieren wenn der Thread noch läuft? den Aufrufer solange zu blockieren widerspricht wohl dem Sinn des ganzen,
die Aktion ablehnen oder als Aufgabe ablegen zur Verarbeitung bei nächster Gelegenheit?
kann man alles hier individuell oder schöner etwas allgemein formuliert basteln,
ob schon fertig vorhanden?..
ExecutorService mag ein Thema sein, hier auch bei JavaFX erwähnt 1 Concurrency in JavaFX (Release 8)
gibt sogar Executors.newSingleThreadExecutor();
Also Synchonizesd ist 'ne ziemlich schlechte Lösung, weil man sich dann den Aufwand mit dem Thread hätte sparen können.
Üblicher weise schalten man den Button so lange auf disabled, bis die Query abgearbeitet ist. Das Reaktivieren macht man dann über einen Listener. Mit FX lässt sich das ja prima über Property-Binding lösen…
natürlich nur dorthin zu synchronisieren, wo geprüft werden kann ob ein Thread läuft usw., was ja schnell geht,
alles andere, obwohl ich selber auch was soll denn passieren wenn der Thread noch läuft? den Aufrufer solange zu blockieren widerspricht wohl dem Sinn des ganzen,
geschrieben hatte, ist schon komische Interpretation…
ein ExecutorService wird intern auch jede Menge synchronized haben, ist doch nicht per se negativ?
[quote=SlaterB]wird intern auch jede Menge synchronized haben, ist doch nicht per se negativ?[/quote]Wer schrieb denn was von “negativ”?
Der Punkt ist: wenn ich irgendwo das Schlüsselwort synchronized verwende heißt dass im Klartext “Warte bis fertig” und der wartende Thread ist dann eben so lange blockiert. Der Worker-Thread wurde aber genau deswegen eingeführt, weil der EDT eben nicht warten soll.
Jetzt klar?
Wenn “Synchonisation” allgemeiner ohne Verwendung von synchronized gemeint war kam das für mich so nicht rüber, zumal auch kein alternativer Ansatz zum synchonized gegeben wurde.
synchronized steht für exklusiven Zugriff, etwa um in 0.0000001 sec sicher nachschauen zu können ob ein Thread läuft oder ein boolean gesetzt ist,
doch nicht ausschließlich oder primär dafür, Threads vor einer langen Methode warten zu lassen…
und nochmal: das wobei ich schon selber davon geschrieben habe was soll denn passieren wenn der Thread noch läuft? den Aufrufer solange zu blockieren widerspricht wohl dem Sinn des ganzen,
also ein Warten ganz und gar nicht in meinem Sinne sein konnte…, undenkbare Annahme
hier vielleicht?
aber auch das wirst du dir wohl alles zurechtdrehen können…
[quote=SlaterB]aber auch das wirst du dir wohl alles zurechtdrehen können…[/quote]Kann ich:
synchonized is nicht “per se” schlecht, nur im konkreten Fall.
:idea:
[QUOTE=Timothy_Truckle;123568]Also Synchonizesd ist 'ne ziemlich schlechte Lösung, weil man sich dann den Aufwand mit dem Thread hätte sparen können.
Üblicher weise schalten man den Button so lange auf disabled, bis die Query abgearbeitet ist. Das Reaktivieren macht man dann über einen Listener. Mit FX lässt sich das ja prima über Property-Binding lösen…
bye
TT[/QUOTE]
Das werde ich machen, so ist es eindeutig das etwas passiert und trotzdem arbeitet die GUI weiter. Ich habe mir bereits überlegt dem Benutzer das laden zu synchronisieren. Das kann ich mir mit dem disable schenken.