<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.Semaphore;

public class ProdConsSemaphore {
	private static int N = 10;
	private static producer p = new producer(); // producer thread
	private static consumer c = new consumer(); // consumer thread
	private static Semaphore empty = new Semaphore(N);
	private static Semaphore full = new Semaphore(0);
	private static Semaphore mutex = new Semaphore(1);
	private static Queue&lt;Integer&gt; buffer = new LinkedList&lt;Integer&gt;();
	private static boolean done = false;

	private static class producer extends Thread {
		private int val = 0;

		public void run() {// run method contains the thread code
			while (!done) { // producer loop
				try {
					int item = produce_item();
					empty.acquire(); // down to get a permit for empty spot
					mutex.acquire(); // down to get mutex permit
					System.out.print("p " + item + " ");
					Thread.sleep(40);  // 50 ms delay to stress system
					buffer.add(item); // add item to fill promised empty spot
					mutex.release(); // up to release mutex
					full.release(); // up to check in permit for filled spot
				} catch (InterruptedException e) {
					System.out.println("problem with producer");
				}
			}
		}

		private int produce_item() {
			return ++val;
		}
	}

	private static class consumer extends Thread {
		private int ckval = 0;

		public void run() {// run method contains the thread code
			while (!done) { // consumer loop
				try {
					full.acquire(); // down, to get a permit for filled spot
					mutex.acquire();
					int item = buffer.remove(); // get promised filled spot item
					System.out.print("c " + item + " ");
					Thread.sleep(50);
					mutex.release();
					empty.release(); // up, to check in permit for empty sp
					consume_item(item);
				} catch (InterruptedException e) {
					System.out.println("problem with consumer");
				}
			}
		}

		private void consume_item(int item) {
			++ckval; // value we expect to get
			if (item != ckval) {
				System.out.println("unexpected val " + item);
			}
		}
	}

	public static void main(String args[]) {
		System.out.println("starting p");
		p.start(); // start the producer thread
		System.out.println("starting c");
		c.start(); // start the consumer thread
		try {
			Thread.sleep(5000); // run 5 secs
		} catch (InterruptedException ex) {
		}
		done = true; // tell threads to quit looping
	}
}
</pre></body></html>