Skip to content

Instantly share code, notes, and snippets.

@pedrominicz
Last active March 15, 2020 13:12
Show Gist options
  • Save pedrominicz/822a421c41f0b42410f235839468a15c to your computer and use it in GitHub Desktop.
Save pedrominicz/822a421c41f0b42410f235839468a15c to your computer and use it in GitHub Desktop.
Producer-Consumer example in Java.
import java.util.LinkedList;
import java.util.Queue;
public class Consumer {
public static void main(final String[] args) {
// `Channel` is a singleton class defined below.
final Channel channel = Channel.INSTANCE;
// Producer thread. The only noticeable curiosity about it is that is
// makes use of anonymous classes.
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; true; ++i) {
try {
channel.send(i);
// `Thread::sleep` may throw `InterruptedException`
// which must be caught.
Thread.sleep(1000);
} catch (InterruptedException ie) {
// Empty.
}
}
}
}).start();
// Consumer thread.
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
// `Channel::receive` may throw `InterruptedException`
// which must be caught.
System.out.println(channel.receive());
} catch (InterruptedException ie) {
// Empty.
}
}
}
}).start();
}
// Singleton class representing an integer channel. This is a singleton
// class and not just a bunch of static methods because it uses
// `Object::notify` and `Object::wait`.
private static class Channel {
public static final Channel INSTANCE = new Channel();
private static final Queue<Integer> queue = new LinkedList<Integer>();
// `synchronized` enforces that only one thread accesses this function
// at any given time. `synchronized` works on a per object basis,
// however `Channel` is a singleton class.
public synchronized void send(final int i) {
queue.add(i);
// Notify waiting thread. There is no point calling
// `Object::notifyAll` because the first thread to wake-up will
// empty the queue.
notify();
}
public synchronized int receive() throws InterruptedException {
if (queue.size() == 0) {
// Forces current thread to wait until `Object::notify` or
// `Object::notifyAll` is called in another thread.
//
// Note that `Object::wait` may throw `InterruptedException`.
wait();
}
return queue.remove();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment