InterruptedException: Wie behandeln?

beginner99

Aktives Mitglied
Hallo zusammen,

wie der Titel besagt, ist es mir nicht ganz klar, wie ich mit InterruptedException umgehen sollte.
Soll man die Loggen?

Was ich habe:

"Daten-Threads", die aus Datenbank lesen
"Such-Thread", der anhand der Daten etwas tut (spezielle Suche mit Treffer Limit)

Nun ist es so, dass der Such-thread abgebrochen werden kann, wenn das Treffer Limit erreicht wurde, also zB. nach 1000 Treffern abbrechen. Das ist so auch möglich dank InterruptedException (java.util.concurrent.Future.cancel() oder ExecutorService.shutdownNow()).

Das Problem ist nun auch, dass ich somit die InterruptedException für einen normal zu erwartendes Verhalten verwende, also kein spezieller Zustand. Loggen der Exception macht dann kaum Sinn. Ist das akzeptabel? Oder gibt es eine andere Möglichkeit?
 

Volvagia

Top Contributor
Ich würde nichts tun, da eine InterruptedException immer von dir explizit ausgelöst wird.
Ich würde den Thread aber beenden, indem er die Suchschleife verlässt, wenn das Trefferlimit erreicht wurde.
 

Blakh

Bekanntes Mitglied
Wieso nicht im Suchthread normal mit einer Zählvariable abbrechen lassen anstatt den Thread von aussen zu interrupten?
 

Raziell

Bekanntes Mitglied
Wie Volvagia schon sagte würde ich das ganze so machen:

Java:
@override
public void run(){
 while(!limitReached){
  // search
 }
}

limitReached kannst du dann setzen, wann du willst.

Ist meiner Meinung nach die sauberste Lösung, weil man Threads nicht mit Gewalt beenden soll.
 
Zuletzt bearbeitet:

FArt

Top Contributor
Ich würde das ganze so machen:

Java:
@override
run(){
 while(!limitReached){
  // search
 }
}

limitReached kannst du dann setzen, wann du willst.

Ist meiner Meinung nach die sauberste Lösung, weil man Threads nicht mit Gewalt beenden soll.

Nein, interrupt ist die sinnvollste Lösung, weil man eine InterruptedException oft sowieso behandeln muss. Warum ein künstliches Flag einführen, wenn Thread bereits einen Mechanismus vorhält?

[JavaSpecialists 056] - Shutting down threads cleanly
 

Raziell

Bekanntes Mitglied
Nein, interrupt ist die sinnvollste Lösung, weil man eine InterruptedException oft sowieso behandeln muss. Warum ein künstliches Flag einführen, wenn Thread bereits einen Mechanismus vorhält?

[JavaSpecialists 056] - Shutting down threads cleanly

Hm ok, dann habe ich mich wohl falsch informiert :D
 

tfa

Top Contributor
Hm ok, dann habe ich mich wohl falsch informiert :D

Ich find's nicht besonders geschickt, Exceptions zur Kontrollflusssteuerung zu missbrauchen. Wenn ein Thread in seiner run()-Methode berechnen kann, ob er beendet werden möchte oder nicht, soll er das auch tun. Eine einfache klar forumulierte Abbruchbedingung reicht, meinetwegen auch mit Flag-Variablen. Warum mit InterruptedExceptions werfen? Das ist doch viel schwieriger zu verstehen.

Anders ist es, wenn ein Thread "von Außen" abgebrochen werden soll.
 

FArt

Top Contributor
Ich find's nicht besonders geschickt, Exceptions zur Kontrollflusssteuerung zu missbrauchen. Wenn ein Thread in seiner run()-Methode berechnen kann, ob er beendet werden möchte oder nicht, soll er das auch tun. Eine einfache klar forumulierte Abbruchbedingung reicht, meinetwegen auch mit Flag-Variablen. Warum mit InterruptedExceptions werfen? Das ist doch viel schwieriger zu verstehen.

Anders ist es, wenn ein Thread "von Außen" abgebrochen werden soll.

Mehr als ungeschickt. Ich ging wegen der Formulierung "Nun ist es so, dass der Such-thread abgebrochen werden kann" davon aus, dass dieser Trigger von Außen kommt.

Regulären Programmfluß nie mit Ausnahmen regeln: Exception-Handling Antipatterns | Java.net
 

beginner99

Aktives Mitglied
Ich habe mich vermutlich zu kurz gefasst oder das ganze falsch erklärt.

Der Suchthread beendet sich schon selbst via Zähler. Er nimmt aber die Daten aus einer BlockingQueue und diese Queue wird von Datenthreads gefüttert. Ein Datenthread hat keine Ahnung vom Zähler und wird momentan per InterruptedException gestoppt.
Das ganze ist nötig, da nicht alle Daten auf einen Schlag geladen werden können wegen Speicherverbrauch.

Ein Datenthread ist JDBC + Objekt Erstellung (DataaccessLayer). Die Methode getData() vom DataaccessLayer erstellt die Datenthreads selbst. Der Aufrufer hat also keine Möglichkeit den Vorgang zu stoppen, ausser den thread zu interrupten.
 
M

maki

Gast
Dir ist klar dass man sowas normalerweise mit einer "fetch size" löst?
D.h. dass die Methode des Data Access Layer welche du zum suchen nutzt auch ein Parameter hat wieviele er maximal holen soll, dadurch lässt sich das sehr einfach mit JDBC umsetzen und du brauchst deine Krücke nicht mehr, und dein code wird klarer.
 

beginner99

Aktives Mitglied
Dir ist klar dass man sowas normalerweise mit einer "fetch size" löst?
D.h. dass die Methode des Data Access Layer welche du zum suchen nutzt auch ein Parameter hat wieviele er maximal holen soll, dadurch lässt sich das sehr einfach mit JDBC umsetzen und du brauchst deine Krücke nicht mehr, und dein code wird klarer.

Ja, nur gilt das nicht für alle RDBMS. Einigie ignorieren diesen Wert einfach (was so auch erlaubt ist gemäss JDBC Spezifikation) und laden die gesamte Abfrage auf einmal. Und der DAL sollte die üblichen gratis OpenSource RDBMS (zb HSQLDB) auch unterstützen.
Und das laden der Daten bzw. das erstellen der Objekte aus diesen ist der langsamste Teil, nicht die Suche selbst.
 

beginner99

Aktives Mitglied
*bump*

Hier mal noch code. Genau gesehen brauche ich die InterrruptedException nicht für Kontrollfluss.
Ich will einfach einen Thread stoppen, da er sonst ewig weiterläuft.

Java:
// screeningHits = BlockingQueue; moleculeFetcher = Callable
// mache weiter solange die Trefferzahl nicht erreicht wurde und
// es Elemente in der Queue hat oder noch weitere Daten geladen werden.
while (totalHitsFound < maxHits 
		&& (screeningHits.size() > 0 || !moleculeFetcher.isDone())) {
	IMolecule mol = screeningHits.poll(100, TimeUnit.MILLISECONDS);
	if (mol != null) {                        
		// snipped, do work
		totalHitsFound++;
	}
}

moleculeFetcher.cancel(true); //<- das beschriebene Problem.
// Wenn ich moleculeFetcher nicht beende, wird er nie fertig,
// da sobald die BlockingQueue voll ist, er einfach ewig wartet,
// da sie ja nicht mehr entleert wird.
 

Ähnliche Java Themen

Neue Themen


Oben