Java スケジュールされたエグゼキュータでの未処理の例外
-
12-09-2019 - |
質問
次の問題があり、正確に何が起こっているのか知りたいです。Java を使用しています ScheduledExecutorService 5 分ごとにタスクを実行します。とてもうまくいきます。Executor は、Java でスレッド プログラミングを行う方法を完全に変えました。
ここで、スケジュールされたタスクがハンドルされない例外で失敗した場合の動作についての情報を求めて Java Doc を参照しましたが、何も見つかりませんでした。
次にスケジュールされたタスクはまだ実行されますか?未処理の例外がある場合、スケジュールされた実行プログラムはタスクのスケジュールを停止しますか?誰かがこの単純な問題に関する情報を指摘してもらえますか?
どうもありがとう。
解決
scheduleAtFixedRate
とscheduleWithFixedDelay
両方のJavadocは、「タスクのいずれかの実行が例外に遭遇した場合、後続の実行が抑制されている。」と言います私はそれが正確に透き通ったことを見つけることはありませんが、それはあなたのrun
メソッドが例外のいずれかの種類をスローした場合、スケジューラは、効果的にそのタスクをドロップしますと言っているように見えます。そのスケジューラ経由で実行されている他のタスクは影響を受けません。それは、それが実際に何をするかテストするために難しいことではありません...
タスクのキャンセルは、必ずしも悪いことではないかもしれません。 runメソッドがRuntimeException
をスローした場合、それはおそらくどこかのバグを持っているし、システムの状態は不明です。しかし、最低でも、私はあなたのrunメソッドでRuntimeException
をキャッチし、SEVEREでフルスタックトレースをログ記録助言します。その後、状況に応じて、タスクをキャンセルする再スローすることをお勧めします。しかし、どちらかの方法は、あなたは何が悪かったのか、ワークアウトの戦いのチャンスを持っているログが必要になります。
他のヒント
使用している場合 scheduleAtFixedRate()
または scheduleAtFixedDelay()
, 、タスクが例外でベイルアウトした場合、そのタスクは再スケジュールされません。ただし、他の独立したタスクは引き続き期待どおりに実行されるはずです。(見る APIドキュメント)。これが起こったことが気になる場合は、 ScheduledFuture
それが返されて、 get()
方法。基礎となるタスクが例外をスローした場合、その例外は get()
メソッドでラップされた ExecutionException
.
この男は同じ問題を抱えています。
のhttp://code.nomad- labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/する
彼の解決策が実行可能内Exception
をキャッチすることであり、RuntimeException
を投げる再ます:
try {
theRunnable.run();
} catch (Exception e) {
// LOG IT HERE!!!
System.err.println("error in executing: " + theRunnable + ". It will no longer be run!");
e.printStackTrace();
// and re throw it so that the Executor also gets this error so that it can do what it would
// usually do
throw new RuntimeException(e);
}
API には特定の例外処理メカニズムが定義されていないようです。つまり、キャッチされなかった例外はスレッド フレームを通過するだけで、最終的には stderr に記録されます。
次の例外処理戦略を活用できることがわかりました。
- オブジェクトがスレッドプールに送信されるタスクのクラスでハンドラーを定義します。
- あなた自身のものを提供してください スレッドファクトリー を介してデフォルトのハンドラーを初期化するスレッドプールへの実装 setUncaughtExceptionHandler() または ThreadGroup の uncaughtException();