2011-01-12 5 views
2

ScheduledExecutorServiceを使用して定期的に実行するためにRunnableをスケジュールし、OutOfMemoryのようなシステムエラーが発生したとします。それは静かに飲み込まれます。ScheduledExecutorService throwable lost

scheduler.scheduleWithFixedDelay(new Runnable() { 
        @Override 
        public void run() { 
         throw new OutOfMemoryError(); // Swallowed 
        } 
       }, 0, delay, TimeUnit.SECONDS); 

正常ですか?

なぜそれがコンテナに伝播しないのですか?

このようなエラーを処理する正しい方法は何ですか?

ありがとうございます!

答えて

2

のサブタイプと同様に、OutOfMemoryErrorは、回復できません。これらは一般にプログラムにとって致命的です。あなたが試してキャッチしてもいなくても、あなたのプログラムはダウンしていても大したことではありません。

  1. キャッチあなたのタスクのrun()メソッド内からの例外:

    場合は、しかし、あなたはExceptionではなくErrorを意味し、その後、2つのオプションがあります。

  2. get()scheduleWithFixedDelay()で返します。これにより、例外が送信スレッドに戻されますが、それが発生するまでブロックされます。
1

このメソッドはScheduledFutureインスタンスを返します。このメソッドは、(タイムアウトの有無にかかわらず)OutOfMemoryErrorを原因としてExecutionExceptionをスローします。

+0

繰り返し可能なタスクをスケジューリングした後にfuture.get()を呼び出すようにアドバイスしますか?しかし、それは眠っているスレッドの作成を引き起こします。大丈夫ですか? –

+1

さて、仕事が完了するまで例外が投げられたかどうかは分からないので、何らかの理由でそれが成功するか、失敗するか(例外またはエラーを投げる)待たなければなりません。タイムアウト0でgetを呼び出すと、ジョブがまだ実行中の場合、メソッドはTimeoutExceptionをスローします。返されたFutureのステータスを問い合わせるためにスレッドをブロックする必要はありません。 – jarnbjo

0

ListenableFutureクラスのguavaがここで役立つ場合があります。

これを使用すると、エラーを記録し、失敗したタスクを再開しようとする例外ハンドラタスクを作成できます。

あなたはまだ例外を監視するためにスリープ中のスレッドが必要ですが、あなただけの全体のプロセスのための1つのグローバル例外ハンドラスレッド必要があります(というより、各スケジュールされたタスクに1つずつ。)

0

個人的に私はあなたのオブジェクトソーン種類を与えるだろう例外処理のためのフレームワークを期待するのではなく、例外を報告するメカニズムを提供します。例外リスナーなどと考えてください。

オームについては、あなたができることはほとんどありません。

これらのエグゼクティブは、あなたのコードが持つ可能性のあるすべての問題を処理しないようにあなたのものを実行するためにそこを食べました!誰もがrunnable.run()呼び出すとき

import com.jcabi.log.VerboseRunnable; 
Runnable runnable = new VerboseRunnable(
    Runnable() { 
    public void run() { 
     // do business logic, may Exception occurs 
    } 
    }, 
    true // it means that all exceptions will be swallowed and logged 
); 

は今、例外がスローされません:

0

あなたはすべての例外をキャッチし、それらをログに記録しますjcabi-logからVerboseRunnableクラスを、使用することができます。代わりに、それらは飲み込まれ、(SLF4Jに)記録されます。

関連する問題