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    }