views:

262

answers:

3
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 and ExecutionException in the code? And in what cases are these exceptions thrown?

A: 

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";
        }
    }
}
Jon Skeet
if i call Thread.interrupt(), the interrupt flag is set to true. But InterruptedException is not thrown
java_geek
It does not have to be an unchecked exception. `Callable.call()` can throw anything.
finnw
@finnw: Absolutely right. Sorry to have missed that.
Jon Skeet
@java_geek: You need to interrupt the *waiting* thread - see my edited post for an example.
Jon Skeet
+1  A: 

This article has some advice on how to handle InterruptedException.

finnw
+1  A: 

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 shut down or pause your threads 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 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. So it is an instance of an exception being used to change logic 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.

Nathan Hughes