在什么情况下,Future.get()会抛出ExecutionException或InterruptedException

jav*_*eek 25 java multithreading future executorservice interrupted-exception

我的代码片段:

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();
}
Run Code Online (Sandbox Code Playgroud)

我应该如何处理InterruptedExceptionExecutionException代码?

在什么情况下,抛出这些异常?

Nat*_*hes 39

ExecutionException并且InterruptedException是两个非常不同的东西.

ExecutionException包装正在执行的线程抛出的任何异常,所以如果你的线程是,例如,做某种导致IOException被抛出的IO ,那将被包裹在ExecutionException并重新抛出.

一个InterruptedException不是任何出错的迹象.它是为您提供一种方法,让您的线程知道什么时候停止,以便他们可以完成当前的工作并优雅地退出.假设我希望我的应用程序停止运行,但我不希望我的线程丢弃他们正在做的事情(如果我做了它们的守护程序线程会发生什么).因此,当应用程序被关闭时,我的代码在这些线程上调用中断方法,它们在它们上设置中断标志,下次这些线程正在等待或休眠时,它们检查中断标志并抛出一个InterruptedException,我可以使用它从线程所参与的无限循环处理/休眠逻辑中解脱出来.(如果线程没有等待或休眠,它只能定期检查中断标志.)因此,它是一个异常的实例,用于改变逻辑流程.您完全记录它的唯一原因是在示例程序中向您显示正在发生的事情,或者您是否正在调试中断逻辑无法正常工作的问题.


Jon*_*eet 7

InterruptedException如果interrupt在计算完成之前在等待线程上调用,则抛出该函数.

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";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)