例外を食べているように見えるScheduledThreadPoolExecutorがあります。送信したRunnableが例外をスローした場合に、Executorサービスから通知を受けたい。
たとえば、次のコードでは、少なくともIndexArrayOutOfBoundsExceptionのstackTraceを出力してください。
threadPool.scheduleAtFixedRate(
new Runnable() {
public void run() {
int[] array = new array[0];
array[42] = 5;
}
},
1000,
1500L,
TimeUnit.MILLISECONDS);
副次的な質問として。 ScheduledThreadPoolExecutorの一般的なtry catchブロックを作成する方法はありますか?
/////////// END OF ORIGINAL QUESTION //////////////
提案されているように、次のデコレーターはうまく機能します。
public class CatcherTask implements Runnable{
Runnable runMe;
public CatcherTask(Runnable runMe) {
this.runMe = runMe;
}
public void run() {
try {
runMe.run();
} catch (Exception ex){
ex.printStackTrace();
}
}
}
この問題について少し前に post を書きました。次の2つのオプションがあります。
UncaughtExceptionHandler
を割り当てる代わりに、実際に実行される(run
を呼び出す)独自の実行可能ファイルに実際の実行可能ファイルをラップしますtry-catch-block内で実行できます。[〜#〜]編集[〜#〜]
マークが指摘したように、Runnable
に渡されたものではなく、ScheduledExecutorService
に渡されたThreadFactory
をラップすることが重要です。
警告:このメソッドは、scheduledスレッドプールエグゼキューターには適用されません。この回答は、他のスレッドプールエグゼキューターとの関連性から削除されていません。 Willi's answer を参照してください。
ThreadFactory
をオーバーライドして、スレッドにUncaughtExceptionHandlerを与えます。
ThreadPoolExecutor exec = new ThreadPoolExecutor...;
exec.setThreadFactory(new ExceptionCatchingThreadFactory(exec.getThreadFactory()));
//go on to submit tasks...
private static class ExceptionCatchingThreadFactory implements ThreadFactory {
private final ThreadFactory delegate;
private ExceptionCatchingThreadFactory(ThreadFactory delegate) {
this.delegate = delegate;
}
public Thread newThread(final Runnable r) {
Thread t = delegate.newThread(r);
t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
e.printStackTrace(); //replace with your handling logic.
}
});
return t;
}
}
get()
を呼び出すことで、取得しているFuture
からscheduleAtFixedRate()
メソッドを使用できます。スレッドの実行中に例外が発生した場合は、ExecutionException
がスローされます。
Spring Framework のThreadPoolTaskScheduler
を使用して、エラーハンドラーを設定するメソッドを公開し、すべてのラッピングを行うこともできます。デフォルトの動作は、タスクのタイプによって異なります。
提供されたErrorHandler
がnullでない場合、それが使用されます。それ以外の場合、繰り返しタスクにはデフォルトでエラーが抑制されますが、ワンショットタスクにはデフォルトでエラーが伝搬されます。これらのエラーは返されたFuture
を介して予期されるためです。どちらの場合も、エラーがログに記録されます。
TaskScheduler
ではなく、ラッピングパーツのみを使用する場合は、
TaskUtils.decorateTaskWithErrorHandler(task, errorHandler, isRepeatingTask)
TaskScheduler
が内部で使用します。
ScheduledThreadPoolExecutorをサブクラス化し、 afterExecute メソッドをオーバーライドして、送信するあらゆる種類のRunnableの例外とエラーを処理できます。