Select in Logo

Our example demonstrates how to use Java’s ExecutorService and Future to simulate the behavior of select in concurrent operations. We’ll use these to wait on multiple asynchronous tasks.

import java.util.concurrent.*;
import java.util.Arrays;
import java.util.List;

public class Select {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(2);

        // We'll create two Callable tasks for our example
        Callable<String> task1 = () -> {
            Thread.sleep(1000);
            return "one";
        };

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

        // Submit the tasks to the executor
        List<Future<String>> futures = executor.invokeAll(Arrays.asList(task1, task2));

        // We'll use CompletableFuture.anyOf to simulate the select behavior
        CompletableFuture<Object> cf1 = CompletableFuture.anyOf(
            futures.get(0).thenApply(CompletableFuture::completedFuture),
            futures.get(1).thenApply(CompletableFuture::completedFuture)
        );

        CompletableFuture<Object> cf2 = CompletableFuture.anyOf(
            futures.get(0).thenApply(CompletableFuture::completedFuture),
            futures.get(1).thenApply(CompletableFuture::completedFuture)
        );

        // Wait for and print the results
        System.out.println("received " + cf1.get());
        System.out.println("received " + cf2.get());

        executor.shutdown();
    }
}

In this example, we use Java’s concurrency utilities to simulate the behavior of select across two channels:

  1. We create an ExecutorService with two threads.
  2. We define two Callable tasks that sleep for different durations before returning a value, simulating blocking operations.
  3. We submit these tasks to the executor and get a list of Future objects.
  4. We use CompletableFuture.anyOf twice to wait for either of the tasks to complete, simulating the select behavior.
  5. We print the results as they arrive.

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.

This Java implementation provides similar functionality to the original example, using Java’s concurrency mechanisms to handle multiple asynchronous operations simultaneously.