Select in Minitab

Our example demonstrates how to use Java’s concurrency features to wait on multiple operations simultaneously. We’ll use ExecutorService and Future to simulate the behavior of Go’s select statement.

import java.util.concurrent.*;

public class Select {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        // Create an ExecutorService to manage our threads
        ExecutorService executor = Executors.newFixedThreadPool(2);

        // Create two Callable tasks, each simulating a channel operation
        Callable<String> task1 = () -> {
            Thread.sleep(1000);
            return "one";
        };

        Callable<String> task2 = () -> {
            Thread.sleep(2000);
            return "two";
        };

        // Submit tasks to the executor and get Future objects
        Future<String> future1 = executor.submit(task1);
        Future<String> future2 = executor.submit(task2);

        // Wait for both tasks to complete and print the results
        for (int i = 0; i < 2; i++) {
            if (future1.isDone()) {
                System.out.println("received " + future1.get());
                future1 = null;
            } else if (future2.isDone()) {
                System.out.println("received " + future2.get());
                future2 = null;
            } else {
                Thread.sleep(100); // Wait a bit before checking again
            }
        }

        // Shutdown the executor
        executor.shutdown();
    }
}

In this example, we use Java’s ExecutorService to manage concurrent tasks. We create two Callable tasks, each simulating a channel operation that completes after a certain amount of time.

We submit these tasks to the executor and receive Future objects, which represent the pending results of the asynchronous computations.

We then enter a loop where we check if either of the futures has completed. If a future is done, we print its result and set it to null to avoid checking it again. If neither future is done, we sleep for a short time before checking again.

This approach simulates the behavior of Go’s select statement, allowing us to wait on multiple concurrent operations and handle them as they complete.

To run the program, compile and execute it:

$ javac Select.java
$ java Select
received one
received two

Note that the total execution time is only about 2 seconds, even though we have one task that takes 1 second and another that takes 2 seconds. This is because both tasks are executed concurrently.

While this Java implementation doesn’t have the elegance of Go’s select statement, it demonstrates how to achieve similar functionality using Java’s concurrency utilities.