001 /*
002 * $Id: BoundedBuffer.java,v 1.7 2004/01/16 17:19:02 kredel Exp $
003 */
004
005 //package edu.unima.ky.parallel;
006 package thread;
007
008 /**
009 * A bounded buffer has some capacity to store objects.
010 * With the method <code>put</code> objects are placed into
011 * the buffer, and with the <code>get</code> objects are taken
012 * from the buffer.
013 * <code>put</code> blocks if there is no space to
014 * place a object into the buffer.
015 * <code>get</code> blocks if there are no objects in the buffer.
016 * The objects are put to and get from the buffer in FIFO order.
017 * @author Akitoshi Yoshida
018 * @author Heinz Kredel.
019 * see Queue
020 * @see Deque
021 * see Channel
022 * see MemoryChannel
023 * see SyncChannel
024 * see Stack
025 */
026
027 public class BoundedBuffer extends Object {
028
029 /**
030 * The buffer storage of objects.
031 */
032 private Object[] buffer;
033
034 /**
035 * The size of the buffer.
036 */
037 private int size;
038
039 /**
040 * The position of the first filled cell.
041 */
042 private int front;
043
044 /**
045 * The position of the first empty cell.
046 */
047 private int rear;
048
049 /**
050 * A semaphore to indicate an empty buffer.
051 */
052 private Semaphore empty;
053
054 /**
055 * A semaphore to indicate a full buffer.
056 */
057 private Semaphore full;
058
059 private Object pt;
060 private Object gt;
061
062 /**
063 * Constructs a BoundedBuffer with a desired size.
064 * @param init the size of the buffer.
065 */
066 public BoundedBuffer(int init) {
067 buffer = new Object[init];
068 size = init;
069 front = 0;
070 rear = 0;
071 empty = new Semaphore(init);
072 full = new Semaphore(0);
073 pt = new Object();
074 gt = new Object();
075 }
076
077
078 /**
079 * Tests if the BoundedBuffer is empty.
080 * If it is, gives back the value true.
081 * @return The boolean value of
082 (whether the BoundedBuffer is empty or not).
083 */
084 public boolean empty() {
085 return (front == rear);
086 }
087
088
089 /**
090 * Add an object to the BoundedBuffer
091 * @param v object to be added to the buffer.
092 */
093 public void put(Object v) throws InterruptedException {
094 empty.P();
095 synchronized (pt) {
096 if (rear >= size) rear -= size;
097 buffer[ rear ] = v;
098 rear++;
099 }
100 full.V();
101 }
102
103 /**
104 * Get an object from the BoundedBuffer
105 * @return next object in buffer.
106 * @throws InterruptedException
107 */
108 public Object get() throws InterruptedException {
109 Object v;
110 full.P();
111 synchronized (gt) {
112 if (front >= size) front -= size;
113 v = buffer[ front ];
114 front++;
115 }
116 empty.V();
117 return v;
118 }
119 }