4

次のコードを実行しようとしています。

public static void main(String[] args){
    ScheduledExecutorService service = new ScheduledThreadPoolExecutor(2);

    Runnable r = new Runnable() {
        @Override
        public void run() {
            throw new RuntimeException();
        }
    };
    service.execute(r );
    ScheduledFuture<?> schedule = service.schedule(r, 0, TimeUnit.SECONDS);
    new Thread(r).run();
}

上記に関して、以下の質問があります。

  1. エグゼキューターのスレッドで発生する例外をキャッチして応答する方法はありますか?
  2. 作成されたスレッドからの例外がメイン スレッドに明示的に伝播されるのに、executor サービスを使用した両方の実行でそのエラーが伝播されないのはなぜですか? このエラーはどのようにして発見できますか?

編集:もう1つの質問が頭に浮かびました:

  1. スケジュールした特定の定期的なタスクを停止するにはどうすればよいですか? たとえば、N 回の繰り返しまたは N 分後に言いましょう。
4

2 に答える 2

7

質問 2 は非常に簡単です。実際に新しいスレッドを開始するのではなくrun()、元のスレッドで同期的に実行される を呼び出すだけです。を呼び出す必要があります。start()その時点で、例外は伝播されません。

ScheduledExecutorService-で例外を処理する場合は、元のタスクが例外をスローした場合Future.get()にスローExecutionExceptionされ、元の例外が原因として公開されます。

例外のスローによって中止されたタスクの結果を取得しようとしたときにスローされる例外。この例外は、Throwable.getCause()メソッドを使用して調べることができます。

将来の完了をブロックせずに例外に応答する必要がある場合はRunnable、元のメソッドに委任されたばかりの別のもので「本物」をラップできますrun()が、適切な try/catch ブロックを使用します。

于 2012-10-09T22:14:38.637 に答える
6

次のようにキャッチできます。

    ScheduledFuture<?> schedule = service.schedule(r, 0, TimeUnit.SECONDS);
    try {
        Object get = schedule.get();
    } catch (InterruptedException ex) {
        ex.printStackTrace();
    } catch (ExecutionException ex) {
        ex.printStackTrace();
    }

で実行されているコードが例外を(Scheduled)ExecutorService スローFuture.get()した場合、ラップされた呼び出し時に再スローされますExecutionException

編集:

スケジュールされたタスクの停止については、すでに議論され、解決されています。

于 2012-10-09T22:15:20.523 に答える