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.