В каких случаях есть Future.get () бросать ExecutionException или прерываниеException

StackOverflow https://stackoverflow.com/questions/2665569

Вопрос

Мой кодовый фрагмент:

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 в коде?

И в каких случаях брошены эти исключения?

Это было полезно?

Решение

ExecutionException а также InterruptedException два очень разных вещания.

ExecutionException обернуты любые исключения, которые выполняются нить, поэтому, например, если ваша нить была, например, какой-то какой-то IO, который вызвал IOException быть брошенным, это будет обернуто в ExecutionException и рихроун.

Ан. InterruptedException не является признаком того, что пошло не так. Это там, чтобы дать вам способ позволить своим потокам знать, когда пришло время остановиться, чтобы они могли закончить свою текущую работу и изящно выходить из которых. Скажи, что я хочу, чтобы мое приложение прекратило бегать, но я не хочу, чтобы мои темы бросали то, что они делают в середине чего-либо (что произойдет, если бы я сделал их нитью демона). Таким образом, когда приложение отключается, мой код вызывает метод прерывания в этих потоках, которые устанавливают флаг прерывания на них, и в следующий раз эти потоки ждут или спят, они проверяют флаг прерывания и бросят InterruptedException, который я могу использовать для выхода из любой линии обработки / спящей логики бесконечной петли, нити занимаются. (И если нить не ждет или спать, он может просто проверить флаг прерывания периодически.) Так что это экземпляр исключения, используемого для изменения логического потока. Единственная причина, по которой вы вообще вообще вообще вообще вообще вообще входит в примере, чтобы показать вам, что происходит, или если вы отладываете проблему, где логика прерывания не работает правильно.

Другие советы

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";
        }
    }
}

Статья разработчиков IBM Работа с прерываниемException. есть несколько советов о том, как справиться InterruptedException.

Пример кода для возврата трех типов исключений.

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.: Исключение, брошенное при попытке получить результат задачи, прерванной, бросая исключение => вычисление бросило исключение

В приведенном выше примере это Exception моделируется через ArithmeticException: / by zero

Как правило, вы должны поймать его исправить корневую причину, если оно тривиально, как указано в примере.

ПрерываниеException.: Брошенный, когда нить ждет, спят или иным образом занята, а нить прерывается либо до, либо во время активности.

В приведенном выше примере это Exception моделируется путем прерывания текущей резьбы во время ExecutionException.

Как правило, вы должны поймать его, не действуйте на это.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top