Channel Synchronization in Groovy

We can use channels to synchronize execution across threads. Here’s an example of using a blocking receive to wait for a thread to finish. When waiting for multiple threads to finish, you may prefer to use a CountDownLatch.

import java.util.concurrent.CountDownLatch

// This is the function we'll run in a separate thread. The
// CountDownLatch will be used to notify the main thread that
// this function's work is done.
def worker(CountDownLatch latch) {
    print "working..."
    Thread.sleep(1000)
    println "done"

    // Countdown to notify that we're done.
    latch.countDown()
}

// Start a worker thread, giving it the CountDownLatch to notify on.
def latch = new CountDownLatch(1)
Thread.start { worker(latch) }

// Block until we receive a notification from the worker thread.
latch.await()

To run the program:

$ groovy channel-synchronization.groovy
working...done

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

In this Groovy example, we use a CountDownLatch to achieve similar functionality to Go’s channel synchronization. The CountDownLatch is initialized with a count of 1, and the worker thread calls countDown() when it’s finished. The main thread waits for the latch to reach zero with the await() method, effectively blocking until the worker is done.

The Thread.start { ... } syntax in Groovy is used to create and start a new thread, which is analogous to Go’s goroutines. While not as lightweight as goroutines, it serves a similar purpose in this context.

This example demonstrates a basic form of thread synchronization in Groovy, which is conceptually similar to the channel synchronization shown in the original example.