← Back to Home

Module 2 - Futures

Module Overview

Explore Callable interfaces and Future objects for asynchronous programming, enabling efficient non-blocking operations in your Java applications.

Understanding the Callable Interface

The Callable interface represents a task that returns a result and can throw an exception. This makes it more powerful than Runnable, which cannot return a value or throw checked exceptions.

Key differences between Callable and Runnable:

// Implementing Callable using lambda syntax
Callable<String> task = () -> {
    // Some computation that returns a value
    return "Task completed successfully";
};

// Submitting a Callable to an ExecutorService
ExecutorService executor = Executors.newCachedThreadPool();
Future<String> future = executor.submit(task);

Working with Future Objects

A Future represents the result of an asynchronous computation. It provides methods to check if the computation is complete, wait for its completion, and retrieve the computation result.

When working with Future objects, remember:

// Retrieving results from a Future with exception handling
Future<String> future = executor.submit(task);
try {
    // Block until the result is available
    String result = future.get();
    System.out.println("Task result: " + result);
} catch (InterruptedException e) {
    // Handle thread interruption
    Thread.currentThread().interrupt();
} catch (ExecutionException e) {
    // Handle exceptions thrown by the task
    Throwable cause = e.getCause();
    System.err.println("Task failed: " + cause.getMessage());
}

Minimizing Blocking with Future

Waiting for a Future result can block your thread, but there are techniques to minimize blocking time.

Strategies include:

// Using a timeout to limit blocking time
Future<String> future = executor.submit(task);
try {
    // Wait for at most 2 seconds
    String result = future.get(2, TimeUnit.SECONDS);
    System.out.println("Task result: " + result);
} catch (TimeoutException e) {
    // Handle the timeout
    System.out.println("Task took too long, cancelling");
    future.cancel(true);
} catch (InterruptedException | ExecutionException e) {
    // Handle other exceptions
}

Learning Objectives

Resources