1. Overview
In this article, we will learn about the Java interface java.util.concurrent.Future along with examples.
2. Java java.util.concurrent Future interface
The java.util.concurrent.Future is an interface introduced in Java 5 and added to the java.util.concurrent
package. The Future is basically a placeholder to hold the result of a task that is not completed yet.
A Future represents the result of an asynchronous computation. The provided methods allow us to check if the computation is complete, wait for its completion, and to retrieve the result of the computation.
A CompletableFuture introduced later in Java 8 also implements the Future interface. This article focuses on the Future interface. However, to know the CompletableFuture, refer to these articles.
The ExecutorService
executes a task and updates the result in the Future.
The ExecutorService
provides submit method which takes a value-returning task (Runnable or Callable) for execution and returns a Future representing the pending results of the task.
Once the task completes, the Future will contain the result.
3. Future with Callable example
In the following code, the main thread submits a Callable
task that returns an Integer value as the result to the ExecutorService
. The ExecutorService executes the Callable and updates the result in the future instance upon completion.
public static void main(String[] args) { ExecutorService exec = Executors.newSingleThreadExecutor(); Future<Integer> future = exec.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { System.out.println("Performing mathematical computation.."); return 25; } }); }
The submitter (main thread) of the task can use the Future object to get the result by using the get()
method. Note that this get()
is a blocking call that blocks the main thread and waits for the result.
try { System.out.println(f.get()); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
4. Future with Runnable example
In the following code, the main thread submits a Runnable
task to the ExecutorService
. The ExecutorService
executes the Runnable. Since Runnable doesn’t return any result, printing runnableFuture.get()
gives you null.
Future<?> runnableFuture = exec.submit(new Runnable() { @Override public void run() { System.out.println("Executing Runnable"); } }); try { System.out.println(runnableFuture.get()); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
5. Interrupt the thread
If you want to interrupt the background thread once we triggered the task, then you can use the Future.cancel(boolean mayInterruptIfRunning)
to tell the executor to stop the execution and interrupt its caller thread.
For example, the following runnableFuture
execution is interrupted by the cancel
method.
Future<?> runnableFuture = exec.submit(new Runnable() { @Override public void run() { System.out.println("Executing Runnable START"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Executing Runnable END"); } }); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } runnableFuture.cancel(true);
When you execute the above code, the runnableFuture
is interrupted and throws the following error:
Executing Runnable START java.lang.InterruptedException: sleep interrupted at java.base/java.lang.Thread.sleep(Native Method) at com.tedblob.java.CompletableFuture.FutureDemo$2.run(FutureDemo.java:29) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) at java.base/java.lang.Thread.run(Thread.java:832) Executing Runnable END
6. Conclusion
To sum up, we have discussed the Java interface java.util.concurrent.Future along with examples. These examples are available in our GitHub repository.
Pingback: Thread executor in Java - TedBlob