2015-12-10 5 views
5

Ich habe eine nicht kleine mehrere Threads Anwendung mit GUI und Socket-Kommunikation. Während der Entwicklung fand ich manchmal, dass es einige Ausnahmen gibt, die nicht gefangen und protokolliert werden. Ich muss auf die Konsole starren, um sie zu holen, wenn es welche gibt.Wie werden alle nicht abgefangenen Ausnahmen von verschiedenen Threads während der Entwicklung an einer Stelle abgefangen?

Gibt es eine Möglichkeit, diese nicht abgefangenen Ausnahmen von verschiedenen Threads (einschließlich EDT) an einem Ort zu fangen, in main() zu sagen, und sie zu protokollieren? Ich stelle einen Versuch-Catch in Haupt(), um die Throwable zu fangen, aber es funktioniert nicht.

EDIT:

Speziellere, ich habe Executors.newCachedThreadPool() mit Runnable s. Ich möchte nicht Callable in vielen Fällen verwenden, weil ich nicht meinen Anruf Thread blockieren möchte. Wie kann ich dann Ausnahmen von diesen Runnables abfangen?

Und auch, wie kann ich fangen u ncaught Ausnahme vom Swing-EDT?

+0

Verwenden Sie einen Thread.UncaughtExceptionHandler wie in [dieser Frage] (http://stackoverflow.com/questions/6546193/how-to-catch-an-exception-from-a-thread) – DaniEll

+1

uhm ... warum tun Sie denken, dass Callable den Calling-Thread blockiert? Das macht überhaupt keinen Sinn, es ist so, als ob Bananen wegen ihres Geschmacks die Erderwärmung verursachen ... "Callable" ist eine "funktionale Schnittstelle" und kann auf viele Methodensignaturen angewendet werden - das hat nichts mit blockierenden Operationen zu tun. .. überhaupt. "Callable" blockiert nur, wenn der Aufrufer keine Threads verwendet - das Austauschen des Callable für ein Runnable ändert das nicht. – specializt

Antwort

6

Ich würde vorschlagen, einen benutzerdefinierten Handler des Typs UncaughtExceptionHandler für nicht gefangenen Ausnahmen mit Methode Thread.setDefaultUncaughtExceptionHandler. Dieser Handler wird von JVM aufgerufen, wenn der Thread aufgrund einer nicht abgefangenen Ausnahme beendet wird.

Thread.setDefaultUncaughtExceptionHandler((Thread t, Throwable e) -> { 
      System.out.println(t + " throws exception: " + e); 
    }); 

UPD:

Wie für Swing EDT Fall, ich glaube, es gibt nette Antwort here.

+0

Ich habe deine Lösung für einige meiner Threads bekommen. Aber ich habe auch einen Thread Pool und den Swing EDT. Wie man mit ihnen umgeht? Bitte sehen Sie meine Bearbeitung. – peterboston

-1

Kein einfaches Problem in einem großen komplexen Programm, weil es keine Möglichkeit gibt, eine Ausnahme in einem anderen Thread als dem, der es ausgelöst hat, abzufangen. Sie müssen sicherstellen, dass jeder Thread im Programm einen Handler hat, der alle Ausnahmen abfängt und sie meldet.

Das ist einfach genug, wenn Sie den Code steuern, der alle Threads erstellt, aber schwieriger, wenn Sie Bibliotheksroutinen aufrufen, die in Ihrem Namen Threads erstellen. Wenn Sie Glück haben, können Sie in den Bibliotheken ThreadFactory angeben, damit Ihr Code bei der Erstellung eines neuen Threads die Kontrolle übernehmen kann.

Auch wenn Sie sicherstellen können, dass jeder Thread einen nicht abgefangenen Exception-Handler hat, der das Richtige tut, haben Sie möglicherweise irgendwo Code versteckt (vielleicht in einer 3rd-party-Bibliothek, die Sie aufrufen), die eine Ausnahme abfängt und ignoriert es.

Viel Glück!

+1

das ist ... einfach unwahr. Ich empfehle, keine Antworten zu Themen zu schreiben, die Ihnen fremd sind. Ausnahmen propagieren/sprudeln und es ist tatsächlich extrem einfach alles zu fangen, siehe den ersten Kommentar unter der Frage. – specializt

+2

@specializt Es ist nicht so einfach, eine Ausnahme zu fangen, wenn es zu Code aufbliesst, der nicht deins ist, und es ist nicht so einfach, eine Ausnahme zu fangen, wenn es in Code gefangen und ignoriert wird, der nicht deins ist. –

+0

das ist eine komplett andere Geschichte, die nichts mit normalen, unberechtigten Ausnahmen zu tun hat. – specializt

Verwandte Themen