Range Over Channels in Logo

Our first example demonstrates how to iterate over values received from a channel using Java’s concurrent programming features.

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class RangeOverChannels {
    public static void main(String[] args) throws InterruptedException {
        // We'll iterate over 2 values in the queue.
        BlockingQueue<String> queue = new LinkedBlockingQueue<>(2);
        queue.put("one");
        queue.put("two");

        // This loop iterates over each element as it's
        // received from queue. Because we've added only
        // two elements, the iteration terminates after
        // receiving these 2 elements.
        while (!queue.isEmpty()) {
            String elem = queue.take();
            System.out.println(elem);
        }
    }
}

When you run this program, you’ll see:

$ javac RangeOverChannels.java
$ java RangeOverChannels
one
two

In this example, we’ve used Java’s BlockingQueue interface and its LinkedBlockingQueue implementation to simulate the behavior of Go’s buffered channels. The put method is used to add elements to the queue, similar to sending values on a channel in Go.

The while loop and take method combination in Java serves a similar purpose to the for range loop over a channel in Go. The take method blocks until an element becomes available, then retrieves and removes that element from the queue.

This example also demonstrates that it’s possible to continue receiving values from a non-empty queue even after we’ve stopped adding new elements to it.

Note that Java’s concurrency model is different from Go’s. While Go uses goroutines and channels for concurrent programming, Java traditionally uses threads and various synchronization mechanisms. The BlockingQueue interface is part of Java’s java.util.concurrent package, which provides higher-level concurrency utilities.