Last mod: 2024.12.21
Java threads - Executors, Callable and Future
The Callable and Future interfaces were introduced in Java 5, which came out in 2004. They were added as part of the java.util.concurrent library, which was part of a larger upgrade to manage concurrency in Java.
ExecutorService, Callable and Future
Starting a thread:
ExecutorService executor = Executors.newFixedThreadPool(3); // We start a pool of 3 threads.
// Threads exceeding these 3 will wait for a free thread in the pool
executor.submit(() -> {
System.out.println("Task in executor");
});
Waiting for result:
ExecutorService executor = Executors.newFixedThreadPool(3);
Future<Double> future = executor.submit(() -> {
for (int i = 1; i <= 10; i++) { // example of long executing code
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("Thread iteration " + i);
}
return Math.random();
});
System.out.println("Result: " + future.get()); // Waiting and read result
executor.shutdown();
Example of callable:
Callable<Double> task = () -> {
Thread.sleep(1_000);
return Math.random();
};
Future<Double> future = Executors.newSingleThreadExecutor().submit(task);
System.out.println("Result: " + future.get());
Thread cancellation:
ExecutorService executor = Executors.newFixedThreadPool(3);
Future<Double> future = executor.submit(() -> {
for (int i = 1; i <= 10; i++) { // example of long executing code
try {
Thread.sleep(1_000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("Thread iteration " + i);
}
return Math.random();
});
Thread.sleep(5_000L);
future.cancel(true); // Thread cancellation after 5 seconds
Thread.sleep(10_000L);
executor.shutdown();
Asynchronics tasks
CompletableFuture allows for asynchronous operations with the ability to combine them and handle errors:
CompletableFuture.supplyAsync(() -> "Data")
.thenApply(data -> data + " processed")
.thenAccept(System.out::println);