/* Producers-Consumers with a 2-positions buffer */ /* Multithreads implementation */ /* File Producers_Consumers_2B.java */ /* ****************************************** */ /* Main program */ /* ****************************************** */ public class Producers_Consumers_2B { public static void main(String[] args) { Buffer2 b = new Buffer2(); new Producer(b,1).start(); new Producer(b,2).start(); new Producer(b,3).start(); new Consumer(b,1).start(); new Consumer(b,2).start(); } } /* ****************************************** */ /* Producer */ /* ****************************************** */ class Producer extends Thread { private Buffer2 buff; private int id; public Producer(Buffer2 b, int n) { buff = b; id = n; } public void run() { try { while (!isInterrupted()) { sleep((long)(java.lang.Math.random()*1000)); buff.put(id); System.out.println("Producer " + id + " puts a datum"); } } catch (InterruptedException e) { return; } } } /* ****************************************** */ /* Consumer */ /* ****************************************** */ class Consumer extends Thread { private Buffer2 buff; private int id; public Consumer(Buffer2 b, int n) { buff = b; id = n; } public void run() { try { while (!isInterrupted()) { sleep((long)(java.lang.Math.random()*1000)); int k = buff.get(); System.out.println("consumer " + id + " has retrieved the datum put by producer " + k); } } catch (InterruptedException e) { return; } } } /* ****************************************** */ /* Buffer */ /* ****************************************** */ class Buffer1 { private int content; private boolean is_empty; public Buffer1() { is_empty = true; } public synchronized void put(int k) throws InterruptedException { while (!is_empty) wait(); content = k; is_empty = false; notifyAll(); } public synchronized int get() throws InterruptedException { while (is_empty) wait(); is_empty = true; notifyAll(); return content; } public synchronized boolean is_full() { return !is_empty; } } class Buffer2 { private Buffer1 first, second; private class Demon extends Thread { private Buffer1 from, to; //Buffer1 is the 1 pos. buffer, defined as before public Demon(Buffer1 f, Buffer1 t){ from = f; to = t; } public void run() { try { while (!isInterrupted()) { if (!(to.is_full())) synchronized (from) { int k = from.get(); to.put(k); } } //synch. on from is to avoid the presence of 3 data at the same time } catch (InterruptedException e) { return; } } } public Buffer2(){ first = new Buffer1(); second = new Buffer1(); new Demon(first,second).start(); } public void put(int k) throws InterruptedException { first.put(k); } public int get() throws InterruptedException { return second.get(); } } /* ****************************************** */