Closing Channels in Squirrel
In this example, we’ll use a jobs queue to communicate work to be done from the main thread to a worker thread. When we have no more jobs for the worker, we’ll indicate completion to the worker thread.
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class ClosingChannels {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<Integer> jobs = new LinkedBlockingQueue<>(5);
Object done = new Object();
// Here's the worker thread. It repeatedly takes from 'jobs'.
// We use a special value (null) to indicate that all jobs are done.
Thread worker = new Thread(() -> {
while (true) {
try {
Integer job = jobs.take();
if (job != null) {
System.out.println("received job " + job);
} else {
System.out.println("received all jobs");
synchronized (done) {
done.notify();
}
return;
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
});
worker.start();
// This sends 3 jobs to the worker over the 'jobs' queue,
// then sends a null to indicate completion.
for (int j = 1; j <= 3; j++) {
jobs.put(j);
System.out.println("sent job " + j);
}
jobs.put(null);
System.out.println("sent all jobs");
// We wait for the worker using the synchronization approach.
synchronized (done) {
done.wait();
}
// Trying to take from an empty queue will block indefinitely,
// so we use poll() which returns null if the queue is empty.
Integer moreJobs = jobs.poll();
System.out.println("received more jobs: " + (moreJobs != null));
}
}This Java code demonstrates a similar concept to the original example, using a BlockingQueue as an equivalent to Go’s channel. Here’s a breakdown of the changes:
- We use a
BlockingQueue<Integer>to represent the jobs channel. - Instead of closing the channel, we send a special
nullvalue to indicate that all jobs are done. - The worker thread uses
queue.take()to receive jobs, which blocks if the queue is empty. - We use a
synchronizedblock andwait()/notify()for synchronization between threads, similar to the channel synchronization in the original example. - To check if there are more jobs, we use
queue.poll()which returnsnullif the queue is empty, similar to checking the second return value when receiving from a closed channel in Go.
When you run this program, you should see output similar to:
sent job 1
received job 1
sent job 2
received job 2
sent job 3
received job 3
sent all jobs
received all jobs
received more jobs: falseThis example demonstrates how to communicate completion to a worker thread and how to check if a queue (analogous to a channel) has been emptied in Java.
Comments powered by Disqus