Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to add a timeout to a task

Short answer

Future.get() with a timeout waits no longer than the given time and throws a TimeoutException:

void main() throws Exception {
    try (var pool = Executors.newSingleThreadExecutor()) {
        Future<String> future = pool.submit(() -> {
            Thread.sleep(2000);
            return "report";
        });
        try {
            IO.println(future.get(300, TimeUnit.MILLISECONDS));
        } catch (TimeoutException e) {
            future.cancel(true);
            IO.println("Too slow, cancelled: " + future.isCancelled());
        }
    }
}

Output:

Too slow, cancelled: true

cancel(true) interrupts the task's thread; otherwise the pool would wait for it to finish when closing.

A default value

completeOnTimeout() supplies a value if the task did not finish in time:

void main() {
    String result = CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                return "fresh data";
            })
            .completeOnTimeout("cached data", 200, TimeUnit.MILLISECONDS)
            .join();
    IO.println(result);
}

Output:

cached data

An error on timeout

orTimeout() completes the task with a TimeoutException:

void main() {
    var future = CompletableFuture.supplyAsync(() -> {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return 42;
    }).orTimeout(200, TimeUnit.MILLISECONDS);
 
    try {
        future.join();
    } catch (CompletionException e) {
        IO.println(e.getCause().getClass().getSimpleName());
    }
}

Output:

TimeoutException

Common mistake

Calling get() without a timeout for tasks that use the network. If the server never answers, the program waits forever. Set a limit both on the operation itself (for example, an HTTP client timeout) and on waiting for the result.

Functions used in this recipe

Thanks for reading!

Donate to the site — we work hard for you.