Timeouts in Java

Timeouts are important for programs that connect to external resources or that otherwise need to bound execution time. Implementing timeouts in Java is possible using the java.util.concurrent package, which provides tools for handling concurrent operations.

import java.util.concurrent.*;

public class Timeouts {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newSingleThreadExecutor();

        // For our example, suppose we're executing an external
        // call that returns its result after 2s.
        Future<String> future1 = executor.submit(() -> {
            Thread.sleep(2000);
            return "result 1";
        });

        try {
            // Here we're implementing a timeout.
            // We'll wait for the result for 1 second.
            String result = future1.get(1, TimeUnit.SECONDS);
            System.out.println(result);
        } catch (TimeoutException e) {
            System.out.println("timeout 1");
        } catch (Exception e) {
            e.printStackTrace();
        }

        // If we allow a longer timeout of 3s, then the operation
        // will succeed and we'll print the result.
        Future<String> future2 = executor.submit(() -> {
            Thread.sleep(2000);
            return "result 2";
        });

        try {
            String result = future2.get(3, TimeUnit.SECONDS);
            System.out.println(result);
        } catch (TimeoutException e) {
            System.out.println("timeout 2");
        } catch (Exception e) {
            e.printStackTrace();
        }

        executor.shutdown();
    }
}

Running this program shows the first operation timing out and the second succeeding.

$ javac Timeouts.java
$ java Timeouts
timeout 1
result 2

In this Java implementation:

  1. We use ExecutorService to manage our asynchronous tasks.
  2. We create Future objects to represent the results of asynchronous computations.
  3. The Future.get(long timeout, TimeUnit unit) method is used to implement the timeout. If the computation doesn’t complete within the specified time, a TimeoutException is thrown.
  4. We use try-catch blocks to handle the potential exceptions, including TimeoutException.

This approach provides similar functionality to the original example, allowing us to bound the execution time of operations and handle timeouts gracefully.