KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lateralnz > common > util > Queue


1 /* ====================================================================
2  * The LateralNZ Software License, Version 1.0
3  *
4  * Copyright (c) 2003 LateralNZ. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by
21  * LateralNZ (http://www.lateralnz.org/) and other third parties."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. The names "LateralNZ" must not be used to endorse or promote
26  * products derived from this software without prior written
27  * permission. For written permission, please
28  * contact oss@lateralnz.org.
29  *
30  * 5. Products derived from this software may not be called "Panther",
31  * or "Lateral" or "LateralNZ", nor may "PANTHER" or "LATERAL" or
32  * "LATERALNZ" appear in their name, without prior written
33  * permission of LateralNZ.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of LateralNZ. For more
51  * information on Lateral, please see http://www.lateralnz.com/ or
52  * http://www.lateralnz.org
53  *
54  */

55 package org.lateralnz.common.util;
56
57 import java.io.Serializable JavaDoc;
58 import java.util.ArrayList JavaDoc;
59
60 import org.lateralnz.common.wrapper.IntHolder;
61
62 /**
63  * a simple queue with a synchronized getter that returns (and removes)
64  * the first object in the list (ie. FIFO). This has an option to support notify()/wait()
65  *
66  * @author J R Briggs
67  */

68 public class Queue implements Serializable JavaDoc, Constants {
69   private InnerArrayList queue = new InnerArrayList();
70   private IntHolder messageIdx = new IntHolder(0);
71   private int cleanupSize = 100;
72   private boolean blocking = false;
73   
74   public Queue() {
75     this(100, false);
76   }
77   
78   public Queue(boolean blocking) {
79     this(100, blocking);
80   }
81   
82   public Queue(int cleanupSize) {
83     this(cleanupSize, false);
84   }
85   
86   public Queue(int cleanupSize, boolean blocking) {
87     this.cleanupSize = cleanupSize;
88     this.blocking = blocking;
89   }
90   
91   public int getSize() {
92     return queue.size() - messageIdx.value;
93   }
94   
95   public synchronized void add(Object JavaDoc obj) {
96     queue.add(obj);
97     
98     if (messageIdx.value > cleanupSize) {
99       int removed = queue.remove(0, cleanupSize);
100       messageIdx.value -= removed;
101     }
102     
103     if (blocking) {
104       try {
105         notify();
106       }
107       catch (IllegalMonitorStateException JavaDoc itme) {
108         System.err.println("illegal monitor state");
109       }
110     }
111   }
112   
113   private boolean available() {
114     if (messageIdx.value >= 0 && messageIdx.value < queue.size()) {
115       return true;
116     }
117     else {
118       return false;
119     }
120   }
121   
122   public synchronized Object JavaDoc get() throws InterruptedException JavaDoc {
123     if (blocking) {
124       while (!available()) {
125         wait();
126       }
127     }
128     
129     Object JavaDoc rtn = null;
130     int idx = messageIdx.value;
131     
132     if (available()) {
133       messageIdx.value++;
134       rtn = queue.get(idx);
135     }
136     
137     return rtn;
138   }
139   
140  /**
141   * an array list that supports removing a range of values (for performance reasons)
142   */

143   private class InnerArrayList extends ArrayList JavaDoc {
144    /**
145     * remove a range beginning at start (inclusive) and ending at end (exclusive)
146     */

147     public int remove(int start, int end) {
148       if (start > size()) {
149         return 0;
150       }
151       if (end > size()) {
152         end = size();
153       }
154       
155       this.removeRange(start, end);
156       return end - start;
157     }
158   }
159   
160   // simple test
161
public static final void main(String JavaDoc[] args) throws Exception JavaDoc {
162     final Queue queue = new Queue(true);
163     final ArrayList JavaDoc test = new ArrayList JavaDoc();
164     
165     final int max = 10000;
166     
167     Thread JavaDoc t = new Thread JavaDoc() {
168       public void run() {
169         java.util.Random JavaDoc rand = new java.util.Random JavaDoc();
170         for (int i = 0; i < max; i++) {
171           queue.add("test" + i);
172           try { sleep(rand.nextInt(5)); } catch (Exception JavaDoc e) { }
173         }
174       }
175     };
176     
177     for (int i = 0; i < 5; i++) {
178       final int idx = i;
179       Thread JavaDoc l = new Thread JavaDoc() {
180         public void run() {
181           java.util.Random JavaDoc rand = new java.util.Random JavaDoc();
182           while (true) {
183             try {
184               System.out.println("#" + idx + " listening");
185               Object JavaDoc obj = queue.get();
186               if (obj == null) {
187                 System.out.println(">>ERROR<<");
188                 System.exit(1);
189               }
190               System.out.println("#" + idx + " got " + obj);
191               test.add(obj);
192               if (test.size() >= max) {
193                 System.exit(0);
194               }
195               sleep(rand.nextInt(10));
196             }
197             catch (Exception JavaDoc e) { }
198           }
199         }
200       };
201       l.start();
202     }
203     
204     t.start();
205   }
206 }
Popular Tags