class myThread extends Thread { myThread() {} // default constructor private static long startTime = System.currentTimeMillis(); protected static void nap(int ms) { try { sleep(ms); } catch (InterruptedException e) { } } protected static long age() { return System.currentTimeMillis()-startTime; } protected static int getarg(int i, int n, String args[]) { int value; try { value = Integer.parseInt(args[i-1]); } catch (ArrayIndexOutOfBoundsException e) { return n; } catch (NumberFormatException e) { return n; } return value; } protected static float getarg(int i, float f, String args[]) { float value; try { value = Float.valueOf(args[i-1]).floatValue(); } catch (ArrayIndexOutOfBoundsException e) { return f; } catch (NumberFormatException e) { return f; } return value; } } class BinarySemaphore { private boolean locked = false; BinarySemaphore() {} // constructors BinarySemaphore(boolean initial) {locked = initial;} BinarySemaphore(int initial) {locked = (initial == 0);} public synchronized void P() { while (locked) { try { wait(); } catch (InterruptedException e) { } } locked = true; } public synchronized void V() { if (locked) notify(); locked = false; } } class Semaphore { private int value = 0; Semaphore() {value = 0;} // constructors Semaphore(int initial) {value = initial;} public synchronized void P() { value--; if (value < 0) { try { wait(); } catch (InterruptedException e) { System.err.println("Semaphore.P: wait InterruptedException"); } } } public synchronized void V() { value++; if (value <= 0) notify(); } } class BoundedBuffer { private int slots = 0; private float[] buffer = null; private int count = 0; private int putIn = 0; private int takeOut = 0; private BinarySemaphore mutex = null; private Semaphore elements = null; private Semaphore spaces = null; private BoundedBuffer() {} // no instantiation without a parameter BoundedBuffer(int slots) { this.slots = slots; System.out.println("BoundedBuffer created with " + slots + " slots"); mutex = new BinarySemaphore(1); elements = new Semaphore(0); spaces = new Semaphore(slots); buffer = new float[slots]; count = 0; takeOut = 0; putIn = 0; } public void deposit(float item) { spaces.P(); buffer[putIn] = item; putIn = (putIn + 1) % slots; mutex.P(); count++; System.out.println("deposit: count = " + count); mutex.V(); elements.V(); } public float fetch() { float item; elements.P(); item = buffer[takeOut]; takeOut = (takeOut + 1) % slots; mutex.P(); count--; System.out.println("fetch: count = " + count); mutex.V(); spaces.V(); return item; } } class aProducer extends myThread { private int num; private int sleepInterval; private BoundedBuffer bb; private aProducer() {} // instantiation without parameters not allowed aProducer(int num, int sleepInterval, BoundedBuffer bb) { // constructor this.num = num; this.sleepInterval = sleepInterval; this.bb = bb; System.out.println("Producer #" + num + " constructed, sleepInterval=" + sleepInterval); } public void run() { int napping; float item; System.out.println("Producer #" + num + " running"); while (true) { napping = (int) (Math.random() * (sleepInterval*1000)); System.out.println("age()=" + age() + " Producer #" + num + " constructing item for " + napping + " ms"); nap(napping); item = (float) Math.random(); System.out.println("age()=" + age() + " Producer #" + num + " wants to deposit item " + item); bb.deposit(item); } } } class aConsumer extends myThread { private int num; private int sleepInterval; private BoundedBuffer bb; private aConsumer() {} // instantiation without parameters not allowed aConsumer(int num, int sleepInterval, BoundedBuffer bb) { // constructor this.num = num; this.sleepInterval = sleepInterval; this.bb = bb; System.out.println("Consumer #" + num + " constructed, sleepInterval=" + sleepInterval); } public void run() { int napping; float item; System.out.println("Consumer #" + num + " running"); while (true) { System.out.println("age()=" + age() + " Consumer #" + num + " wants to consume an item"); item = bb.fetch(); napping = (int) (Math.random() * (sleepInterval*1000)); System.out.println("age()=" + age() + " Consumer #" + num + " consuming item " + item + " for " + napping + " ms"); nap(napping); } } } class driver extends myThread { private driver() {} // prevent instantiation private static int numSlots = 5; private static int napProducer = 2; private static int napConsumer = 2; private static int runInterval = 20; public static void main(String args[]) { numSlots = getarg(1, numSlots, args); napProducer = getarg(2, napProducer, args); napConsumer = getarg(3, napConsumer, args); runInterval = getarg(4, runInterval, args); System.out.println("BBPC: numSlots=" + numSlots + ", napProducer=" + napProducer + ", napConsumer=" + napConsumer + ", runInterval=" + runInterval); BoundedBuffer bb = new BoundedBuffer(numSlots); aProducer theProducer = new aProducer(1, napProducer, bb); aConsumer theConsumer = new aConsumer(1, napConsumer, bb); theProducer.start(); theConsumer.start(); nap(runInterval*1000); theProducer.stop(); theProducer = null; theConsumer.stop(); theConsumer = null; System.out.println("BBPC done"); System.exit(0); } } /* ............... Example compile and run(s) % /homeb/shartley/Java/java/bin/javac bbpc.java % /homeb/shartley/Java/java/bin/java driver BBPC: numSlots=5, napProducer=2, napConsumer=2, runInterval=20 BoundedBuffer created with 5 slots Producer #1 constructed, sleepInterval=2 Consumer #1 constructed, sleepInterval=2 Producer #1 running age()=706 Producer #1 constructing item for 810 ms Consumer #1 running age()=750 Consumer #1 wants to consume an item age()=1553 Producer #1 wants to deposit item 0.0216875 deposit: count = 1 age()=1591 Producer #1 constructing item for 1281 ms fetch: count = 0 age()=1608 Consumer #1 consuming item 0.0216875 for 88 ms age()=1712 Consumer #1 wants to consume an item age()=2892 Producer #1 wants to deposit item 0.325629 deposit: count = 1 age()=2907 Producer #1 constructing item for 648 ms fetch: count = 0 age()=2921 Consumer #1 consuming item 0.325629 for 1659 ms age()=3572 Producer #1 wants to deposit item 0.905767 deposit: count = 1 age()=3586 Producer #1 constructing item for 75 ms age()=3672 Producer #1 wants to deposit item 0.330639 deposit: count = 2 age()=3686 Producer #1 constructing item for 1332 ms age()=4602 Consumer #1 wants to consume an item fetch: count = 1 age()=4614 Consumer #1 consuming item 0.905767 for 308 ms age()=4942 Consumer #1 wants to consume an item fetch: count = 0 age()=4954 Consumer #1 consuming item 0.330639 for 751 ms age()=5032 Producer #1 wants to deposit item 0.840799 deposit: count = 1 age()=5048 Producer #1 constructing item for 163 ms age()=5222 Producer #1 wants to deposit item 0.309836 deposit: count = 2 age()=5237 Producer #1 constructing item for 1080 ms age()=5722 Consumer #1 wants to consume an item fetch: count = 1 age()=5734 Consumer #1 consuming item 0.840799 for 864 ms age()=6332 Producer #1 wants to deposit item 0.281866 deposit: count = 2 age()=6346 Producer #1 constructing item for 505 ms age()=6614 Consumer #1 wants to consume an item fetch: count = 1 age()=6627 Consumer #1 consuming item 0.309836 for 55 ms age()=6702 Consumer #1 wants to consume an item fetch: count = 0 age()=6713 Consumer #1 consuming item 0.281866 for 846 ms age()=6863 Producer #1 wants to deposit item 0.221728 deposit: count = 1 age()=6877 Producer #1 constructing item for 956 ms age()=7572 Consumer #1 wants to consume an item fetch: count = 0 age()=7584 Consumer #1 consuming item 0.221728 for 1619 ms age()=7852 Producer #1 wants to deposit item 0.937879 deposit: count = 1 age()=7866 Producer #1 constructing item for 1100 ms age()=8983 Producer #1 wants to deposit item 0.574658 deposit: count = 2 age()=8997 Producer #1 constructing item for 499 ms age()=9222 Consumer #1 wants to consume an item fetch: count = 1 age()=9234 Consumer #1 consuming item 0.937879 for 586 ms age()=9512 Producer #1 wants to deposit item 0.374546 deposit: count = 2 age()=9526 Producer #1 constructing item for 529 ms age()=9832 Consumer #1 wants to consume an item fetch: count = 1 age()=9844 Consumer #1 consuming item 0.574658 for 1088 ms age()=10072 Producer #1 wants to deposit item 0.0645171 deposit: count = 2 age()=10087 Producer #1 constructing item for 1484 ms age()=10952 Consumer #1 wants to consume an item fetch: count = 1 age()=10964 Consumer #1 consuming item 0.374546 for 770 ms age()=11582 Producer #1 wants to deposit item 0.519687 deposit: count = 2 age()=11596 Producer #1 constructing item for 678 ms age()=11752 Consumer #1 wants to consume an item fetch: count = 1 age()=11765 Consumer #1 consuming item 0.0645171 for 1147 ms age()=12292 Producer #1 wants to deposit item 0.724322 deposit: count = 2 age()=12306 Producer #1 constructing item for 962 ms age()=12932 Consumer #1 wants to consume an item fetch: count = 1 age()=12944 Consumer #1 consuming item 0.519687 for 1767 ms age()=13282 Producer #1 wants to deposit item 0.878702 deposit: count = 2 age()=13297 Producer #1 constructing item for 1461 ms age()=14732 Consumer #1 wants to consume an item fetch: count = 1 age()=14745 Consumer #1 consuming item 0.724322 for 830 ms age()=14772 Producer #1 wants to deposit item 0.155488 deposit: count = 2 age()=14786 Producer #1 constructing item for 980 ms age()=15592 Consumer #1 wants to consume an item fetch: count = 1 age()=15604 Consumer #1 consuming item 0.878702 for 1454 ms age()=15782 Producer #1 wants to deposit item 0.270823 deposit: count = 2 age()=15797 Producer #1 constructing item for 737 ms age()=16553 Producer #1 wants to deposit item 0.21758 deposit: count = 3 age()=16567 Producer #1 constructing item for 804 ms age()=17072 Consumer #1 wants to consume an item fetch: count = 2 age()=17085 Consumer #1 consuming item 0.155488 for 453 ms age()=17382 Producer #1 wants to deposit item 0.100138 deposit: count = 3 age()=17396 Producer #1 constructing item for 555 ms age()=17552 Consumer #1 wants to consume an item fetch: count = 2 age()=17564 Consumer #1 consuming item 0.270823 for 85 ms age()=17662 Consumer #1 wants to consume an item fetch: count = 1 age()=17675 Consumer #1 consuming item 0.21758 for 1641 ms age()=17962 Producer #1 wants to deposit item 0.246954 deposit: count = 2 age()=17977 Producer #1 constructing item for 187 ms age()=18182 Producer #1 wants to deposit item 0.18355 deposit: count = 3 age()=18196 Producer #1 constructing item for 1130 ms age()=19332 Consumer #1 wants to consume an item fetch: count = 2 age()=19352 Producer #1 wants to deposit item 0.0727698 deposit: count = 3 age()=19347 Consumer #1 consuming item 0.100138 for 1009 ms age()=19393 Producer #1 constructing item for 158 ms age()=19573 Producer #1 wants to deposit item 0.220376 deposit: count = 4 age()=19587 Producer #1 constructing item for 1819 ms age()=20422 Consumer #1 wants to consume an item fetch: count = 3 age()=20435 Consumer #1 consuming item 0.246954 for 1542 ms BBPC done % /homeb/shartley/Java/java/bin/java driver 5 5 1 BBPC: numSlots=5, napProducer=5, napConsumer=1, runInterval=20 BoundedBuffer created with 5 slots Producer #1 constructed, sleepInterval=5 Consumer #1 constructed, sleepInterval=1 Producer #1 running age()=530 Producer #1 constructing item for 3809 ms Consumer #1 running age()=569 Consumer #1 wants to consume an item age()=4376 Producer #1 wants to deposit item 0.707449 deposit: count = 1 age()=4415 Producer #1 constructing item for 3861 ms fetch: count = 0 age()=4432 Consumer #1 consuming item 0.707449 for 599 ms age()=5055 Consumer #1 wants to consume an item age()=8296 Producer #1 wants to deposit item 0.445485 deposit: count = 1 age()=8310 Producer #1 constructing item for 4858 ms fetch: count = 0 age()=8325 Consumer #1 consuming item 0.445485 for 869 ms age()=9215 Consumer #1 wants to consume an item age()=13185 Producer #1 wants to deposit item 0.028162 deposit: count = 1 age()=13200 Producer #1 constructing item for 2236 ms fetch: count = 0 age()=13215 Consumer #1 consuming item 0.028162 for 237 ms age()=13465 Consumer #1 wants to consume an item age()=15456 Producer #1 wants to deposit item 0.432711 deposit: count = 1 age()=15471 Producer #1 constructing item for 1493 ms fetch: count = 0 age()=15486 Consumer #1 consuming item 0.432711 for 722 ms age()=16225 Consumer #1 wants to consume an item age()=16976 Producer #1 wants to deposit item 0.75107 deposit: count = 1 age()=16990 Producer #1 constructing item for 3271 ms fetch: count = 0 age()=17005 Consumer #1 consuming item 0.75107 for 664 ms age()=17685 Consumer #1 wants to consume an item age()=20276 Producer #1 wants to deposit item 0.817654 deposit: count = 1 age()=20290 Producer #1 constructing item for 2592 ms fetch: count = 0 age()=20304 Consumer #1 consuming item 0.817654 for 962 ms BBPC done % /homeb/shartley/Java/java/bin/java driver 5 1 5 BBPC: numSlots=5, napProducer=1, napConsumer=5, runInterval=20 BoundedBuffer created with 5 slots Producer #1 constructed, sleepInterval=1 Consumer #1 constructed, sleepInterval=5 Producer #1 running age()=498 Producer #1 constructing item for 897 ms Consumer #1 running age()=536 Consumer #1 wants to consume an item age()=1431 Producer #1 wants to deposit item 0.567698 deposit: count = 1 age()=1469 Producer #1 constructing item for 313 ms fetch: count = 0 age()=1485 Consumer #1 consuming item 0.567698 for 664 ms age()=1800 Producer #1 wants to deposit item 0.411007 deposit: count = 1 age()=1815 Producer #1 constructing item for 601 ms age()=2170 Consumer #1 wants to consume an item fetch: count = 0 age()=2182 Consumer #1 consuming item 0.411007 for 1103 ms age()=2430 Producer #1 wants to deposit item 0.736059 deposit: count = 1 age()=2445 Producer #1 constructing item for 415 ms age()=2870 Producer #1 wants to deposit item 0.979717 deposit: count = 2 age()=2885 Producer #1 constructing item for 917 ms age()=3300 Consumer #1 wants to consume an item fetch: count = 1 age()=3312 Consumer #1 consuming item 0.736059 for 2881 ms age()=3820 Producer #1 wants to deposit item 0.198447 deposit: count = 2 age()=3834 Producer #1 constructing item for 458 ms age()=4310 Producer #1 wants to deposit item 0.975152 deposit: count = 3 age()=4324 Producer #1 constructing item for 306 ms age()=4650 Producer #1 wants to deposit item 0.0189581 deposit: count = 4 age()=4665 Producer #1 constructing item for 571 ms age()=5251 Producer #1 wants to deposit item 0.633621 deposit: count = 5 age()=5264 Producer #1 constructing item for 462 ms age()=5740 Producer #1 wants to deposit item 0.378471 age()=6210 Consumer #1 wants to consume an item fetch: count = 4 age()=6223 Consumer #1 consuming item 0.979717 for 79 ms deposit: count = 5 age()=6238 Producer #1 constructing item for 816 ms age()=6320 Consumer #1 wants to consume an item fetch: count = 4 age()=6332 Consumer #1 consuming item 0.198447 for 4199 ms age()=7070 Producer #1 wants to deposit item 0.36766 deposit: count = 5 age()=7085 Producer #1 constructing item for 910 ms age()=8011 Producer #1 wants to deposit item 0.765426 age()=10550 Consumer #1 wants to consume an item fetch: count = 4 age()=10562 Consumer #1 consuming item 0.975152 for 2831 ms deposit: count = 5 age()=10579 Producer #1 constructing item for 617 ms age()=11210 Producer #1 wants to deposit item 0.346689 age()=13410 Consumer #1 wants to consume an item fetch: count = 4 age()=13424 Consumer #1 consuming item 0.0189581 for 836 ms deposit: count = 5 age()=13440 Producer #1 constructing item for 503 ms age()=13966 Producer #1 wants to deposit item 0.585681 age()=14280 Consumer #1 wants to consume an item fetch: count = 4 age()=14293 Consumer #1 consuming item 0.633621 for 2190 ms deposit: count = 5 age()=14310 Producer #1 constructing item for 10 ms age()=14340 Producer #1 wants to deposit item 0.168645 age()=16500 Consumer #1 wants to consume an item fetch: count = 4 age()=16513 Consumer #1 consuming item 0.378471 for 3301 ms deposit: count = 5 age()=16529 Producer #1 constructing item for 581 ms age()=17122 Producer #1 wants to deposit item 0.76766 age()=19830 Consumer #1 wants to consume an item fetch: count = 4 age()=19843 Consumer #1 consuming item 0.36766 for 655 ms deposit: count = 5 age()=19859 Producer #1 constructing item for 825 ms BBPC done */