import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; import java.util.concurrent.RunnableFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; public class FutureTaskTest { private static final int DELAY_TIME = 10; public static void main(String[] args) throws InterruptedException, ExecutionException { isDoneTest(false); isDoneTest(true); getCallableResultTest(); getRunnableResultTest(); getTimeoutFail(); getExecutionExceptionTest(); } private static void isDoneTest(final boolean throwException) { RunnableFuture future = new FutureTask(new Runnable() { @Override public void run() { if (throwException) { throw new RuntimeException(); } } }, null); // should finish the future future.run(); if (! future.isDone()) { throw new RuntimeException("Future should be done"); } } private static void getCallableResultTest() throws InterruptedException, ExecutionException { final Object result = new Object(); FutureTask future = new FutureTask(new Callable() { @Override public Object call() throws Exception { return result; } }); future.run(); if (future.get() != result) { throw new RuntimeException("Bad result returned: " + future.get()); } } private static void getRunnableResultTest() throws InterruptedException, ExecutionException { final Object result = new Object(); FutureTask future = new FutureTask(new Runnable() { @Override public void run() { // nothing here } }, result); future.run(); if (future.get() != result) { throw new RuntimeException("Bad result returned: " + future.get()); } } private static void getTimeoutFail() throws InterruptedException, ExecutionException { RunnableFuture future = new FutureTask(new Runnable() { @Override public void run() { // wont run } }, null); long startTime = System.currentTimeMillis(); try { future.get(DELAY_TIME, TimeUnit.MILLISECONDS); throw new RuntimeException("Exception should have been thrown"); } catch (TimeoutException e) { long catchTime = System.currentTimeMillis(); if (catchTime - startTime < DELAY_TIME) { throw new RuntimeException("get with timeout did not block long enough"); } } } private static void getExecutionExceptionTest() throws InterruptedException, ExecutionException { FutureTask future = new FutureTask(new Runnable() { @Override public void run() { throw new RuntimeException(); } }, null); future.run(); try { future.get(); throw new RuntimeException("Exception should have thrown"); } catch (ExecutionException e) { // expected } } }