View Javadoc

1   /*
2    * Copyright 2010 Fraunhofer Gesellschaft, Munich, Germany,
3    * for its Fraunhofer Institute for Computer Architecture and Software
4    * Technology (FIRST), Berlin, Germany. All rights reserved.
5    * http://www.first.fraunhofer.de/
6    */
7   
8   package net.kwfgrid.gwes.util;
9   
10  import org.apache.log4j.Logger;
11  
12  /**
13   * Code modified from Data Structures & Problem Solving Using Java
14   * by Mark Allen Weiss, 1998.
15   *
16   * @author Andreas Hoheisel
17   *         (<a href="http://www.andreas-hoheisel.de">www.andreas-hoheisel.de</a>)
18   * @version $Id: Queue.java 1433 2010-11-29 18:06:07Z hoheisel $
19   */
20  public class Queue {
21  
22      /**
23       * log4j logger.
24       */
25      static final Logger logger = Logger.getLogger(Queue.class);
26  
27      private Object[] theArray;
28      private int currentSize;
29      private int front;
30      private int back;
31      final public Object enqueueSync;
32      final public Object isEmptySync;
33      private static final int TIMEOUT = 10000;
34  
35      static final int DEFAULT_CAPACITY = 16;
36  
37      /**
38       * Construct the queue.
39       */
40      public Queue() {
41          enqueueSync = new Object();
42          isEmptySync = new Object();
43          theArray = new Object[DEFAULT_CAPACITY];
44          makeEmpty();
45      }
46  
47      /**
48       * Test if the queue is logically empty.
49       * @return true if empty, false otherwise.
50       */
51      public boolean isEmpty() {
52          return currentSize == 0;
53      }
54  
55      /**
56       * Get the least recently inserted item in the queue.
57       * Does not alter the queue.
58       * @return the least recently inserted item in the queue.
59       */
60      public Object getFront() {
61          if (isEmpty())
62              return null;
63          return theArray[front];
64      }
65  
66      /**
67       * Return and remove the least recently inserted item
68       * from the queue.
69       * @return the least recently inserted item in the queue.
70       */
71      public synchronized Object dequeue() {
72          if (isEmpty())
73              return null;
74          currentSize--;
75  
76          Object returnValue = theArray[front];
77          theArray[front] = null;
78          front = increment(front);
79          if(currentSize == 0) {
80              synchronized(isEmptySync) {
81                  isEmptySync.notifyAll();
82              }
83          }
84          return returnValue;
85      }
86  
87      /**
88       * Insert a new item into the queue.
89       * @param x the item to insert.
90       */
91      public synchronized void enqueue(Object x) {
92          if (currentSize == theArray.length)
93              doubleQueue();
94          back = increment(back);
95          theArray[back] = x;
96          currentSize++;
97          synchronized(enqueueSync) {
98              enqueueSync.notify();
99          }
100     }
101 
102     /**
103      * Make the queue logically empty.
104      */
105     public void makeEmpty() {
106         currentSize = 0;
107         front = 0;
108         back = -1;
109     }
110 
111     /**
112      * Internal method to expand theArray.
113      */
114     private void doubleQueue() {
115         Object[] newArray;
116 
117         newArray = new Object[theArray.length * 2];
118 
119         // Copy elements that are logically in the queue
120         for (int i = 0; i < currentSize; i++, front = increment(front))
121             newArray[i] = theArray[front];
122 
123         theArray = newArray;
124         front = 0;
125         back = currentSize - 1;
126     }
127 
128     /**
129      * Internal method to increment with wraparound.
130      * @param x any index in theArray's range.
131      * @return x+1, or 0 if x is at the end of theArray.
132      */
133     private int increment(int x) {
134         if (++x == theArray.length)
135             x = 0;
136         return x;
137     }
138 
139     /**
140      * Get the current size of the queue
141      */
142     public int getCurrentSize() {
143         return currentSize;
144     }
145 
146     /**
147      * Wait for queue to be empty
148      */
149     public void waitUntilEmpty()
150             throws InterruptedException {
151         logger.debug("waitUntilEmpty() ...");
152         synchronized(isEmptySync) {
153             while(!isEmpty()) isEmptySync.wait(TIMEOUT);
154         }
155         logger.debug("waitUntilEmpty() ... done");
156     }
157 
158     /**
159      * Wait for queue to be filled
160      */
161     public void waitForEnqueue()
162             throws InterruptedException {
163         logger.debug("waitForEnqueue() ...");
164         synchronized(enqueueSync) {
165             while(isEmpty()) enqueueSync.wait(TIMEOUT);
166         }
167         logger.debug("waitForEnqueue() ... done");
168     }
169 
170 }