Timeouts in Fortress

Timeouts are important for programs that connect to external resources or that otherwise need to bound execution time. Implementing timeouts in Java is straightforward using the ExecutorService and Future classes.

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. We use a Callable
        // to represent this operation.
        Callable<String> task = () -> {
            Thread.sleep(2000);
            return "result 1";
        };

        Future<String> future = executor.submit(task);

        try {
            // Here we implement a timeout. We try to get the result
            // of the Future, but we only wait for 1 second. If the
            // task takes longer than 1 second, a TimeoutException
            // will be thrown.
            String result = future.get(1, TimeUnit.SECONDS);
            System.out.println(result);
        } catch (TimeoutException e) {
            System.out.println("timeout 1");
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        // If we allow a longer timeout of 3s, then the Future.get()
        // will succeed and we'll print the result.
        future = executor.submit(task);

        try {
            String result = future.get(3, TimeUnit.SECONDS);
            System.out.println(result);
        } catch (TimeoutException e) {
            System.out.println("timeout 2");
        } catch (InterruptedException | ExecutionException 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 1

In this Java version, we use an ExecutorService to manage our tasks. The Future.get() method with a timeout parameter allows us to implement the timeout functionality. If the task doesn’t complete within the specified time, a TimeoutException is thrown.

The structure of the program is similar to the original, with two tasks: one that times out and another that completes successfully. The main difference is that Java uses exceptions for timeout handling, while the original used channel selection.