I am reading the book Introducing Play Framework: Java Web Application Development (ISBN 978-1-4842-5645-9) and there is this example on Callable
:
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class CallableClient { /** * @param args */ // Step1 : Create a Runnable public static void main(String[] args) { Callable callableTask = new CallableTask(); // Step 2: Configure Executor // Uses FixedThreadPool executor ExecutorService executor = Executors.newFixedThreadPool(2); Future<String> future = executor.submit(callableTask); boolean listen = true; while (listen) { if (future.isDone()) { String result; try { result = future.get(); listen = false; System.out.println(result); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } } executor.shutdown(); } }
My question is, if the computation of the Future
throws and exception, will the while
loop run forever?
In my opinion, yes, it will loop forever.
First, if the Future
computation throws an exception, then
future.isDone()
always evaluates to true
. So we reach the inside of the if
, where the stopping condition can be set. Still Ok.
Second, as per future documentation, when reaching line
result = future.get();
it will always throw ExecutionException
because the computation threw an exception. This exception is caught in the try-catch
block, without reaching the stopping condition precondition, which is
listen = false
Lastly, the above will create an endless cycle.
Is there any mistake in my assumptions or is the author of the example really wrong?
Advertisement
Answer
The program mentioned above cycles forever, if the callable throws an exception.
This is a code snippet with the callable that throws an exceptions. Executing compiled snippet loops forever.
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class CallableClient { public static class CallableTask implements Callable<String> { @Override public String call() throws Exception { throw new Exception(); } } public static void main(String[] args) { Callable<String> callableTask = new CallableTask(); ExecutorService executor = Executors.newFixedThreadPool(2); Future<String> future = executor.submit(callableTask); boolean listen = true; while (listen) { if (future.isDone()) { String result; try { result = future.get(); listen = false; System.out.println(result); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } } executor.shutdown(); } }