39

私のコードスニペット:

ExecutorService executor = Executors.newSingleThreadExecutor();
try {
    Task t = new Task(response,inputToPass,pTypes,unit.getInstance(),methodName,unit.getUnitKey());
    Future<SCCallOutResponse> fut = executor.submit(t);
    response = fut.get(unit.getTimeOut(),TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
    // if the task is still running, a TimeOutException will occur while fut.get()
    cat.error("Unit " + unit.getUnitKey() + " Timed Out");
    response.setVote(SCCallOutConsts.TIMEOUT);
} catch (InterruptedException e) {
    cat.error(e);
} catch (ExecutionException e) {
    cat.error(e);
} finally {
    executor.shutdown();
}

InterruptedExceptionコード内でとをどのように処理する必要がExecutionExceptionありますか?

そして、どのような場合に、これらの例外がスローされますか?

4

3 に答える 3

59

ExecutionExceptionInterruptedException2つの非常に異なるものです。

ExecutionExceptionIOException実行中のスレッドがスローした例外をラップします。たとえば、スレッドがスローされる原因となる何らかのIOを実行している場合、それはラップされて再スローされExecutionExceptionます。

InterruptedException何かがうまくいかなかったことを示すものではありません。これは、スレッドが現在の作業を終了して正常に終了できるように、停止するタイミングをスレッドに通知する方法を提供するためのものです。アプリケーションの実行を停止したいが、スレッドが何かの途中で実行していることをドロップしたくないとします(これは、デーモンスレッドにした場合に発生します)。したがって、アプリケーションがシャットダウンされているとき、私のコードはこれらのスレッドで割り込みメソッドを呼び出し、割り込みフラグを設定します。次にこれらのスレッドが待機またはスリープしているときに、割り込みフラグをチェックして、InterruptedException、これを使用して、スレッドが関与している無限ループ処理/スリープロジックを回避できます(スレッドが待機またはスリープしない場合は、割り込みフラグを定期的にチェックできます)。したがって、これはインスタンスです。論理フローを変更するために使用されている例外の例。ログに記録する唯一の理由は、何が起こっているかを示すサンプルプログラム、または割り込みロジックが正しく機能していない問題をデバッグしている場合です。

于 2010-04-21T21:15:35.430 に答える
8

InterruptedExceptioninterrupt計算が完了する前に待機中のスレッドでが呼び出された場合にスローされます。

ExecutionException関連する計算(Taskこの場合)が例外自体をスローした場合にスローされます。

これをどのように処理するかは、アプリケーションによって異なります。

編集:これは中断されていることのデモンストレーションです:

import java.util.concurrent.*;

public class Test
{
    public static void main(String[] args) throws Exception
    {
        ExecutorService executor = Executors.newFixedThreadPool(2);
        Future<String> future = executor.submit(new SlowCallable());
        executor.submit(new Interruptor(Thread.currentThread()));
        try
        {
            System.out.println(future.get());
        }
        catch (InterruptedException e)
        {
            System.out.println("I was interrupted");
        }
    }

    private static class Interruptor implements Callable<String>
    {
        private final Thread threadToInterrupt;

        Interruptor(Thread threadToInterrupt)
        {
            this.threadToInterrupt = threadToInterrupt;
        }

        public String call() throws Exception
        {
            Thread.sleep(2000);
            threadToInterrupt.interrupt();
            return "interrupted other thread";
        }
    }

    private static class SlowCallable implements Callable<String>
    {
        public String call() throws Exception
        {
            Thread.sleep(5000);
            return "finished";
        }
    }
}
于 2010-04-19T06:41:42.693 に答える
2

3種類の例外を返すサンプルコード。

import java.util.concurrent.*;
import java.util.*;

public class ExceptionDemo{
    public static void main(String args[]){
        int poolSize=1;
        int maxPoolSize=1;
        int queueSize=30;
        long aliveTive=60;
        ArrayBlockingQueue<Runnable> queue= new ArrayBlockingQueue<Runnable>(queueSize);
        ThreadPoolExecutor executor= new ThreadPoolExecutor(poolSize,maxPoolSize,aliveTive,
                        TimeUnit.MILLISECONDS,queue);
        List<Future> futures = new ArrayList<Future>();
        for ( int i=0; i < 5; i++){
            futures.add(executor.submit(new RunnableEx()));
        }
        for ( Iterator it = futures.iterator(); it.hasNext();){
            try {
                Future f = (Future)it.next();
                f.get(4000,TimeUnit.MILLISECONDS);
            }catch(TimeoutException terr){
                System.out.println("Timeout exception");
                terr.printStackTrace();
            }
            catch(InterruptedException ierr){
                System.out.println("Interrupted exception:");
                ierr.printStackTrace();
            }catch(ExecutionException err){
                System.out.println("Exeuction exception:");
                err.printStackTrace();
                Thread.currentThread().interrupt();
            }
        }
        executor.shutdown();
    }
}

class RunnableEx implements Runnable{
    public void run() {
        // code in here
        System.out.println("Thread name:"+Thread.currentThread().getName());
        try{
            Random r = new Random();
            if (r.nextInt(2) == 1){
                Thread.sleep(2000);
            }else{
                Thread.sleep(4000);
            }
            System.out.println("eee:"+1/0);
        }catch(InterruptedException irr){
            irr.printStackTrace();
        }
    }
}

出力:

Thread name:pool-1-thread-1
Timeout exception
Thread name:pool-1-thread-1
java.util.concurrent.TimeoutException
        at java.util.concurrent.FutureTask.get(FutureTask.java:201)
        at ExceptionDemo.main(ExceptionDemo.java:20)
Thread name:pool-1-thread-1
Exeuction exception:
java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:202)
        at ExceptionDemo.main(ExceptionDemo.java:20)
Caused by: java.lang.ArithmeticException: / by zero
        at RunnableEx.run(ExceptionDemo.java:49)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)
Interrupted exception:
java.lang.InterruptedException
        at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:400)
        at java.util.concurrent.FutureTask.get(FutureTask.java:199)
        at ExceptionDemo.main(ExceptionDemo.java:20)
Timeout exception
java.util.concurrent.TimeoutException
        at java.util.concurrent.FutureTask.get(FutureTask.java:201)
Thread name:pool-1-thread-1
        at ExceptionDemo.main(ExceptionDemo.java:20)
Thread name:pool-1-thread-1
Timeout exception
java.util.concurrent.TimeoutException
        at java.util.concurrent.FutureTask.get(FutureTask.java:201)
        at ExceptionDemo.main(ExceptionDemo.java:20)

TimeoutException:ブロッキング操作がタイムアウトしたときにスローされる例外。

上記の例では、一部のタスクはより多くの時間がかかり(4秒のスリープのため)、get()オンの操作をブロックしていますFuture

タイムアウトを増やすか、実行可能タスクを最適化します。

ExecutionException:例外をスローして中止したタスクの結果を取得しようとしたときにスローされた例外=>計算によって例外がスローされました

上記の例では、これExceptionArithmeticException: / by zero

一般に、例で引用されているように些細なことである場合は、根本的な原因を修正するためにそれをキャッチする必要があります。

InterruptedException:スレッドが待機中、スリープ中、またはその他の方法で占有されているときにスローされ、アクティビティの前または最中にスレッドが中断されます。

上記の例では、これExceptionは、の間に現在のスレッドを中断することによってシミュレートされExecutionExceptionます。

一般的に、あなたはそれがそれに作用しないことをキャッチする必要があります。

于 2016-07-01T13:57:11.733 に答える