Channel Synchronization in Java

This example demonstrates how to use threads and synchronization in Java to coordinate execution between different parts of a program. We’ll use a CountDownLatch to synchronize between threads, which is similar to the channel synchronization concept.

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class ThreadSynchronization {

    // This is the method we'll run in a separate thread. The
    // CountDownLatch will be used to notify the main thread
    // that this method's work is done.
    public static void worker(CountDownLatch latch) {
        System.out.print("working...");
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("done");

        // Signal that we're done
        latch.countDown();
    }

    public static void main(String[] args) throws InterruptedException {
        // Create a CountDownLatch with a count of 1
        CountDownLatch latch = new CountDownLatch(1);

        // Start a worker thread, giving it the latch to signal on
        new Thread(() -> worker(latch)).start();

        // Block until we receive a signal from the worker thread
        latch.await();
    }
}

To run the program:

$ javac ThreadSynchronization.java
$ java ThreadSynchronization
working...done

If you removed the latch.await() line from this program, the main thread would exit before the worker thread even started its work.

In this Java version:

  1. We use a CountDownLatch instead of a channel for synchronization.
  2. The worker method is run in a separate thread, similar to a goroutine.
  3. We use Thread.sleep() to simulate work being done, equivalent to time.Sleep() in the original example.
  4. The latch.countDown() call is equivalent to sending a value on the done channel.
  5. The latch.await() call in the main method blocks until the latch is counted down, similar to receiving from the done channel.

This approach achieves the same goal of synchronizing execution between different threads, demonstrating a common pattern in concurrent programming.