import java.io.*; public class PandC_SemaphoreApproach { static int produceSpeed = 200; static int consumeSpeed = 200; public static void main (String args[]) { if (args.length > 0) produceSpeed = Integer.parseInt (args[0]); if (args.length > 1) consumeSpeed = Integer.parseInt (args[1]); Monitor monitor = new Monitor(); new Producer(monitor, produceSpeed); new Consumer(monitor, consumeSpeed); try { Thread.sleep(1000); } catch (InterruptedException e) { } System.exit(0); } } class Monitor { PrintWriter out = new PrintWriter (System.out, true); int token; Semaphore full = new Semaphore(0); Semaphore empty= new Semaphore(1); //get token value int get () { try { full.down(); } catch (InterruptedException e) { } out.println ("Got: " + token); empty.up(); return token; } //set token value void set (int value) { try { empty.down(); } catch (InterruptedException e) { } token = value; out.println ("Set: " + token); full.up(); } } class Semaphore { private int value; public Semaphore (int initial){ value = initial; } synchronized public void up() { value++; notify(); } synchronized public void down() throws InterruptedException { while (value == 0) wait(); value--; } } class Producer implements Runnable { Monitor monitor; int speed; Producer (Monitor monitor, int speed) { this.monitor = monitor; this.speed = speed; new Thread (this, "Producer").start(); } public void run() { int i = 0; while (true) { monitor.set (i++); try { Thread.sleep ((int) (Math.random() * speed)); } catch (InterruptedException e) { } } } } class Consumer implements Runnable { Monitor monitor; int speed; Consumer (Monitor monitor, int speed) { this.monitor = monitor; this.speed = speed; new Thread (this, "Consumer").start(); } public void run() { while (true) { monitor.get(); try { Thread.sleep ((int) (Math.random() * speed)); } catch (InterruptedException e) { } } } }