2016-04-20 6 views
0

In den ausführbaren Aufgaben, die ich meinem benutzerdefinierten ThreadPoolExecutor geben, fange ich alle Throwable. Und dann, anstatt die gleiche Ausnahme zu werfen, werfe ich eine benutzerdefinierte RuntimeException. Ich überschreibe die Methode afterExecute (Runnableable runnable, Throwable throwable) in meinem Executor, und diese Ausnahme steht mir erwartungsgemäß nach der Ausführung zur Verfügung. Ich verstehe, dass mit dieser Ausnahme nichts passieren sollte, weil ich mich darum gekümmert habe. Allerdings wird die Ausnahme zeitweise zum Hauptthread zugelassen, der dann mit der Thread.getUncaughtExceptionHandler() -Anweisung auf System.err gedruckt wird. Ich habe dies bestätigt durch die folgende Platzierung in meiner Anwendung Hauptmethode:ThreadPoolExecutor ermöglicht intermittierend nicht abgefangene Ausnahme bis zum Hauptthread

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { 
    @Override 
    public void uncaughtException(Thread t, Throwable e) { 
     System.err.println("I shouldn't have got here!"); 
    } 
}); 

Jetzt kann ich einfach nichts mehr im Code tut oben, und die Ausgabe zu System.err verhindern, aber ich würde lieber herausfinden, warum die ThreadPoolExecutor lässt Ausnahmen von den Aufgaben entkommen, die ich ihm gebe. Irgendwelche Gedanken darüber, warum das passieren könnte?

+0

_Die Ausnahme wird durch den Hauptthread zugelassen, der dann auf System.err_ gedruckt wird. Was bringt Sie auf den Gedanken, dass es der Hauptthread beim Drucken ist, oder meinen Sie etwas anderes? – Savior

+0

Das 'setDefaultUncaughtExceptionHandler': _Stellen Sie den Standardhandler ein, der aufgerufen wird, wenn ein Thread aufgrund einer nicht abgefangenen Ausnahme abrupt beendet wird und kein anderer Handler für diesen Thread definiert wurde._ Es ist immer noch derselbe Thread, der den Druckvorgang ausgeführt hat. – Savior

+0

Sie müssen uns Ihren benutzerdefinierten 'ThreadPoolExecutor' anzeigen, wenn Sie uns bei der Suche nach einem Leck unterstützen sollen. – Savior

Antwort

1

ThreadPoolExecutor Fänge und wieder wirft Ausnahme von Aufgabe:

try { 
    task.run(); 
} catch (RuntimeException x) { 
    thrown = x; throw x; 
} catch (Error x) { 
    thrown = x; throw x; 
} catch (Throwable x) { 
    thrown = x; throw new Error(x); 
} finally { 
    afterExecute(task, thrown); 
} 

So ist die Ausnahme wird von den Standard-Handler trotzdem behandelt werden.

Wenn Sie den Aufruf von Default-Handler vermeiden möchten, können Sie Ihre Runnable mit FutureTask umbrechen, die Ausnahmen intern beibehält oder einen eigenen Wrapper erstellt, um die Exception an geeigneter Stelle behandeln zu können.

+0

Ah, das habe ich im Code nicht gesehen. Als ich auf den ersten Blick durchging, dachte ich, nach Execute war der "Endpunkt" für den Executor für eine Aufgabe. Anscheinend aus dem Quellcode hast du Recht, es wirft es einfach erneut. Danke, dass du darauf hingewiesen hast. –

+0

Ich akzeptiere Ihre Antwort, weil es ein falsches Denken von meiner Seite darstellt, dass ein executeCute-Aufruf durch den Executor verhindern würde, dass die Ausnahme ausgelöst wird, was der Kern der Frage war. –

0

Wenn Sie ein TPE mit einer beschränkten Warteschlange und einer Rückweisungsrichtlinie CallerRunsPolicy verwenden, wird das Runnable für den übergebenden Thread ohne Ausnahmeumbruch ausgeführt.

Dieser Fall sollte sowieso aus dem Ausnahme-Stack offensichtlich sein.