The interface java.util.concurrent.Future represents the result of an asynchronous computation.
The future interface snippet:
package java.util.concurrent;
....
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);//Attempts to cancel execution of this task
boolean isCancelled();//Returns true if this task has been cancelled
boolean isDone();//Returns true if this task completed.
V get() throws InterruptedException, ExecutionException;//waits and returns the results
V get(long timeout, TimeUnit unit)//waits for at most the given time and returns the results if available
throws InterruptedException, ExecutionException, TimeoutException;
}
The instance of this interface is returned by following methods of ExecutorService:
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
None of the above methods blocks for the task to complete but they return immediately. The returned Future object can be used later to query the result.
Examples
Future.get()
package com.logicbig.example;
import java.util.concurrent.*;
public class FutureGetExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService es = Executors.newSingleThreadExecutor();
Future<Long> futureResult = es.submit(new Callable<Long>() {
@Override
public Long call() throws Exception {
//simulating long running task
Thread.sleep(1000);
System.out.println("returning");
return ThreadLocalRandom.current().nextLong();
}
});
System.out.println("callable submitted");
//after doing other stuff
System.out.println("waiting for result");
Long result = futureResult.get();//blocks until the task finishes
System.out.println(result);
es.shutdown();
}
}
callable submitted waiting for result returning -4447662861767260382
Future.cancel()
package com.logicbig.example;
import java.util.concurrent.*;
public class FutureCancelExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService es = Executors.newSingleThreadExecutor();
Future<Long> futureResult = es.submit(new Callable<Long>() {
@Override
public Long call() throws Exception {
//simulating long running task
Thread.sleep(1000);
System.out.println("returning");
return ThreadLocalRandom.current().nextLong();
}
});
System.out.println("callable submitted");
//after doing other stuff
System.out.println("canceling task");
boolean c = futureResult.cancel(true);
System.out.println(c);
//following will throw java.util.concurrent.CancellationException
//Long result = futureResult.get();
es.shutdown();
}
}
callable submitted canceling task true
Following shows the use of Future.cancel(false) which allows the task to complete.
package com.logicbig.example;
import java.util.concurrent.*;
public class FutureCancelExample2 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService es = Executors.newSingleThreadExecutor();
Future<Long> futureResult = es.submit(new Callable<Long>() {
@Override
public Long call() throws Exception {
System.out.println("task started and running");
Thread.sleep(1000);
System.out.println("returning result");
return ThreadLocalRandom.current().nextLong();
}
});
Thread.sleep(100);
System.out.println("callable submitted");
//after doing other stuff
System.out.println("canceling task");
boolean c = futureResult.cancel(false);
System.out.println(c);
//following will still throw java.util.concurrent.CancellationException
//Long result = futureResult.get();
es.shutdown();
}
}
task started and running callable submitted canceling task true returning result
Using Future without usable result
If we want to use Future for the sake of cancellability but not provide a usable result, we can declare types of the form Future<?> which will return null as a result of the underlying task.
public class FutureNoResultsExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService es = Executors.newSingleThreadExecutor();
Future<?> futureResult = es.submit(new Runnable() {
@Override
public void run() {
//simulating long running task
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
System.out.println("callable submitted");
//after doing other stuff
System.out.println("getting result");
Object o = futureResult.get();
System.out.println(o);
es.shutdown();
}
} callable submitted getting result null
Future.isDone()
This method returns true if task has completed.
public class FutureIsDoneExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService es = Executors.newSingleThreadExecutor();
Future<Long> futureResult = es.submit(new Callable<Long>() {
@Override
public Long call() throws Exception {
//simulating long running task
Thread.sleep(1000);
System.out.println("returning");
return ThreadLocalRandom.current().nextLong();
}
});
System.out.println("callable submitted");
while(!futureResult.isDone()) {
//do some other stuff
Thread.sleep(10);
}
System.out.println("task done");
Long result = futureResult.get();//will not block
System.out.println(result);
es.shutdown();
}
} callable submitted returning task done -1773366881493053319
Example ProjectDependencies and Technologies Used:
|