2

ScheduledExecutorService を使用して Runnable を定期的に実行するようにスケジュールしたところ、OutOfMemory などのシステム エラーが発生したとします。黙って飲み込んでしまいます。

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

それは正常ですか?

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

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

ありがとう!

4

5 に答える 5

2

は、のOutOfMemoryErrorサブタイプと同様Errorに回復できません。通常、これらはプログラムにとって致命的です。キャッチしようとするかどうかは問題ではありません。プログラムはダウンします。

Exceptionただし、ではなくを意味する場合は、次のError2 つのオプションがあります。

  1. run()タスクのメソッド内から例外をキャッチします。
  2. によって返されget()た を呼び出します。これにより、例外がサブミット スレッドに伝播されますが、それが発生するまでブロックされます。Future()scheduleWithFixedDelay()
于 2011-01-12T22:59:45.143 に答える
1

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

于 2011-01-12T22:52:37.090 に答える
0

すべての例外をキャッチしてログに記録するjcabi-log のVerboseRunnableクラスを使用できます。

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
);

これで、だれかが呼び出しrunnable.run()ても例外はスローされません。代わりに、それらは飲み込まれてログに記録されます (SLF4J に)。

于 2013-04-06T05:37:53.830 に答える
0

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

これにより、エラーをログに記録し、失敗したタスクの再起動を試みる例外ハンドラー タスクを作成できます。

例外を監視するためにスリープ状態のスレッドが引き続き必要ですが、(スケジュールされたタスクごとに 1 つではなく) プロセス全体に対して 1 つのグローバル例外ハンドラー スレッドのみが必要です。

于 2011-01-12T23:06:05.180 に答える
0

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

オームの場合、できることはほとんどありません。

これらのエグゼキュータは、コードで発生する可能性のあるすべての問題を処理するのではなく、実行するためにそこで食べました。

于 2011-01-13T01:48:37.913 に答える