Channel Directions in Mercury

Java doesn’t have built-in channels like Go, so we’ll use BlockingQueue as an alternative to demonstrate a similar concept. BlockingQueue allows thread-safe operations for adding and removing elements.

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

public class ChannelDirections {

    // This ping function only accepts a queue for sending values.
    // It would be a compile-time error to try to receive from this queue.
    public static void ping(BlockingQueue<String> pings, String msg) throws InterruptedException {
        pings.put(msg);
    }

    // The pong function accepts one queue for receives (pings)
    // and a second for sends (pongs).
    public static void pong(BlockingQueue<String> pings, BlockingQueue<String> pongs) throws InterruptedException {
        String msg = pings.take();
        pongs.put(msg);
    }

    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> pings = new LinkedBlockingQueue<>(1);
        BlockingQueue<String> pongs = new LinkedBlockingQueue<>(1);

        ping(pings, "passed message");
        pong(pings, pongs);
        System.out.println(pongs.take());
    }
}

When using BlockingQueue as function parameters, you can specify if a queue is meant to only send or receive values by using the appropriate interface. This specificity increases the type-safety of the program.

The ping function only accepts a BlockingQueue for sending values. It would be a compile-time error to try to receive on this queue.

The pong function accepts one BlockingQueue for receives (pings) and a second for sends (pongs).

To run the program:

$ javac ChannelDirections.java
$ java ChannelDirections
passed message

This example demonstrates how to use BlockingQueue in Java to achieve similar functionality to Go’s channel directions. While not an exact parallel, it shows how to implement unidirectional communication between threads in Java.