Timeouts in Logo

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 ExecutorService and Future classes.

import java.util.concurrent.*;

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

        // 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> task1 = () -> {
            Thread.sleep(2000);
            return "result 1";
        };

        Future<String> future1 = executor.submit(task1);

        try {
            // Here we implement a timeout. We wait for the result
            // for up to 1 second. If the task doesn't complete in time,
            // a TimeoutException is thrown.
            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 task
        // will complete and we'll print the result.
        Callable<String> task2 = () -> {
            Thread.sleep(2000);
            return "result 2";
        };

        Future<String> future2 = executor.submit(task2);

        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, we use ExecutorService to manage our tasks and Future to represent the result of an asynchronous computation. The get method of Future allows us to specify a timeout, after which a TimeoutException is thrown if the task hasn’t completed.

This approach provides similar functionality to Go’s select statement with time.After, allowing us to implement timeouts in a clean and effective manner.