Select in Mercury

Our example demonstrates how to wait on multiple channel-like operations in Java. We’ll use ExecutorService and Future to simulate concurrent operations.

import java.util.concurrent.*;

public class Select {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        // We'll use ExecutorService to simulate channels
        ExecutorService executor = Executors.newFixedThreadPool(2);

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

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

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

        // We'll use a loop to wait for both results
        for (int i = 0; i < 2; i++) {
            // This simulates the select statement
            if (future1.isDone()) {
                System.out.println("received " + future1.get());
                future1 = null;  // Mark as processed
            } else if (future2.isDone()) {
                System.out.println("received " + future2.get());
                future2 = null;  // Mark as processed
            } else {
                Thread.sleep(100);  // Wait a bit before checking again
                i--;  // Decrement to retry
            }
        }

        executor.shutdown();
    }
}

In this example, we use ExecutorService and Future to simulate channel-like operations. Each task sleeps for a certain amount of time before returning a value, simulating blocking operations executing concurrently.

We use a loop to check which Future is done, simulating the select statement. When a Future is done, we print its result and mark it as processed.

To run the program:

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

Note that the total execution time is only about 2 seconds since both the 1 and 2 second sleeps execute concurrently.

While Java doesn’t have built-in channels or a select statement like some other languages, we can achieve similar functionality using Java’s concurrency utilities. This example demonstrates how to wait on multiple concurrent operations and process their results as they become available.