質問

とは言え、以下のコード:

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(myRunnable);

また、この myRunnable 投げ RuntimeExcpetion, どうですか?ワンちょっと自分の供給 ThreadFactory 実装 newSingleThreadExecutor() 設定カスタム uncaughtExceptionHandlersの Threads出てくるのです。別の言い方をするラップ myRunnable 現地(匿名) Runnable を含むがtry-catchブロック.ん、ありがとうございまはその他類似の回避策のです。が---なんだかこう汚れを感じるべきではないこの複雑です。ある清潔なソリューション?

役に立ちましたか?

解決

クリーンな問題を回避するには、ExecutorService.submit()の代わりにexecute()を使用することです。これは、あなたがタスクの結果または例外を取得するために使用することができますFutureを返します:

ExecutorService executor = Executors.newSingleThreadExecutor();
Runnable task = new Runnable() {
  public void run() {
    throw new RuntimeException("foo");
  }
};

Future<?> future = executor.submit(task);
try {
  future.get();
} catch (ExecutionException e) {
  Exception rootException = e.getCause();
}

他のヒント

実行時例外をキャッチし、それらを処理する別の実行可能で実行可能なを飾るます:

public class REHandler implements Runnable {
    Runnable delegate;
    public REHandler (Runnable delegate) {
        this.delegate = delegate;
    }
    public void run () {
        try {
            delegate.run ();
        } catch (RuntimeException e) {
            ... your fancy error handling here ...
        }
    }
}

executor.execute(new REHandler (myRunnable));

なぜませ------------ ExecutorService#submit(), を取得し Future 背対応可能なフレームワーク自分の通話の場合 Future#get() ?

skaffmanは、その使用submitに正しいクリーンなアプローチです。別のアプローチは、 ThreadPoolExecutor にサブクラス化することですそして、afterExecute(Runnable, Throwable)をオーバーライドします。あなたがこのアプローチに従った場合の execute(Runnable)呼び出してくださいではなく、submit(Runnable)またはafterExecuteが呼び出されることはありません。

APIの説明毎ます:

  

メソッドの完了時に呼び出されます   与えられたRunnableの実行。この   この方法は、そのスレッドによって呼び出されます   タスクを実行します。 null以外の場合は、   Throwableがキャッチされていないです   RuntimeException または Error の原因となっ   突然終了する実行ます。

     

注:アクションはで囲まれています   (FutureTaskなど)のいずれかのタスク   明示的に、またはのような方法による   提出し、これらのタスクオブジェクトをキャッチし、   計算の例外を維持し、   そう、彼らは突然起こしません   終了、および内部   例外は、これにを渡されていません   方法の。

仕事(Callable または Runnable) に提出する ThreadPoolExecutors に変換されます FuturnTask, 、という名前の小道具が含まれています callable 送信したタスクと同じです。FuturnTask には独自の run 以下のような方法で。すべての例外またはスロー可能オブジェクトがスローされる c.call() 捕らえられ、という名前の小道具に入れられます outcome. 。FuturnTask を呼び出すとき get 方法、 outcome 投げられます

Jdk1.8ソースコードからのFuturnTask.run

public void run() {
        ...
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    // save ex into `outcome` prop
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
        }
        ...
    }

例外をキャッチしたい場合:

      1.スカフマンの答え
      2.ThreadPoolExecutor を新規作成するときに `afterExecute` を上書きします
        @Override
        protected void afterExecute(Runnable r, Throwable t) {
            super.afterExecute(r, t);
            Throwable cause = null;
            if (t == null && r instanceof Future) {
                try {
                    ((Future<?>) r).get();
                } catch (InterruptedException | ExecutionException e) {
                    cause = e;
                }
            } else if (t != null) {
                cause = t;
            }
            if (cause != null) {
                // log error
            }
        }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top