In what cases does Future.get() throw ExecutionException or InterruptedException
Solution 1
ExecutionException
and InterruptedException
are two very different things.
ExecutionException
wraps whatever exception the thread being executed threw, so if your thread was, for instance, doing some kind of IO that caused an IOException
to get thrown, that would get wrapped in an ExecutionException
and rethrown.
An InterruptedException
is not a sign of anything having gone wrong. It is there to give you a way to let your threads know when it's time to stop so that they can finish up their current work and exit gracefully. Say I want my application to stop running, but I don't want my threads to drop what they're doing in the middle of something (which is what would happen if I made them daemon threads). So when the application is being shutdown, my code calls the interrupt method on these threads, which sets the interrupt flag on them, and the next time those threads are waiting or sleeping they check the interrupt flag and throw an InterruptedException
, which I can use to bail out of whatever infinite-loop processing/sleeping logic the threads are engaged in. (And if the thread doesn't wait or sleep, it can just check the interrupt flag periodically.) So it is an instance of an exception being used to change the logical flow. The only reason you would log it at all is in an example program to show you what's happening, or if you're debugging a problem where interrupt logic is not working correctly.
Solution 2
InterruptedException
will be thrown if interrupt
is called on the waiting thread before the computation has completed.
ExecutionException
will be thrown if the computation involved (Task
in this case) throws an exception itself.
How you want to handle this will entirely depend on your application.
EDIT: Here's a demonstration of being interrupted:
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";
}
}
}
Solution 3
Sample code to return three types of Exceptions.
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();
}
}
}
output:
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 : Exception thrown when a blocking operation times out.
In above example, some tasks are taking more time (due to 4 seconds sleep) and blocking operation of get()
on Future
Either increase the time-out or optimize Runnable task.
ExecutionException: Exception thrown when attempting to retrieve the result of a task that aborted by throwing an exception => The computation threw an exception
In above example, this Exception
is simulated through ArithmeticException: / by zero
Generally, you should catch it fix the root cause if it is trivial as quoted in the example.
InterruptedException: Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity.
In above example, this Exception
is simulated by interrupting current Thread during ExecutionException
.
Generally, you should catch it don't act on it.
java_geek
Updated on August 20, 2020Comments
-
java_geek over 3 years
My code snippet:
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(); }
How should i handle the
InterruptedException
andExecutionException
in the code?And in what cases, are these exceptions thrown?
-
java_geek about 14 yearsif i call Thread.interrupt(), the interrupt flag is set to true. But InterruptedException is not thrown
-
Saurabh about 14 yearsIt does not have to be an unchecked exception.
Callable.call()
can throw anything. -
Jon Skeet about 14 years@java_geek: You need to interrupt the waiting thread - see my edited post for an example.
-
G 1 over 6 yearsIs there a way to prevent ExecutionException from throwing, when there is an exception in the processing of a task. Even if you caught the Exception throws in the processing and handles it, it still wraps the exception to ExecutionException and throws it in the get.
-
Ravindra babu over 6 years@downvoter, re-check question and answer. Java official documentation reasons are quoted here.
-
prime about 6 yearsIs there a relationship between InterruptedException and ExecutionException , just to know which one to catch first. In the SO question he catches the InterruptedException first and then the ExecutionException. Will the behavior will be the same if we swap the order ?
-
prime about 6 yearsIs there a relationship between InterruptedException and ExecutionException , just to know which one to catch first. In the SO question he catches the InterruptedException first and then the ExecutionException. Will the behavior will be the same if we swap the order ?
-
prime about 6 yearsIs there a relationship between InterruptedException and ExecutionException , just to know which one to catch first. In the SO question he catches the InterruptedException first and then the ExecutionException. Will the behavior will be the same if we swap the order ?
-
Jon Skeet about 6 years@prime: Both just derive from
Exception
, so swapping the order will make no difference. -
prime about 6 years@JonSkeet thank you for confirming. Are there any easy way to check two exceptions are related or not. Or can we just do it by looking at whether they derive from same or not.
-
Jon Skeet about 6 years@prime: Exactly the latter - just check the documentation. Or switch them round and see whether the code still compiles...
-
prime about 6 years@JonSkeet Ah Compile errors. Forgot about that :) Thank you.
-
Ravindra babu about 6 yearsInterruuptedException should be caught first
-
prime about 6 yearsAny idea why ? Can you give me an example where the order matters
-
Nathan Hughes about 6 years@prime: see stackoverflow.com/a/10964899/217324. Both of the exceptions extend Exception, neither is more specific than the other. Order doesn't matter in this case.
-
Ravindra babu about 6 yearsFor above use case, any order works since they are unrelated in hierarchy. But if you catch parent exception first and child exception later, compile will throw "exception has already been caught"