1 /**********************************************************************
2 * ThreadQueue.java
3 * created on 07.08.2004 by netseeker
4 * $Source: /cvsroot/ejoe/EJOE/src/de/netseeker/ejoe/concurrent/ThreadQueue.java,v $
5 * $Date: 2006/11/10 00:35:14 $
6 * $Revision: 1.25 $
7 *
8 * ====================================================================
9 *
10 * Copyright 2005-2006 netseeker aka Michael Manske
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 * ====================================================================
24 *
25 * This file is part of the ejoe framework.
26 * For more information on the author, please see
27 * <http://www.manskes.de/>.
28 *
29 *********************************************************************/
30
31 package de.netseeker.ejoe.concurrent;
32
33 import java.util.LinkedList;
34 import java.util.logging.Level;
35 import java.util.logging.Logger;
36
37 /***
38 * @author netseeker aka Michael Manske
39 * @since 0.3.0
40 */
41 public class ThreadQueue
42 {
43 private static final Logger logger = Logger.getLogger( ThreadQueue.class.getName() );
44
45 private final LinkedList _list = new LinkedList();
46
47 private long _defaultTimeout = 10000;
48
49 private int _limit = -1;
50
51 /***
52 * Creates a new, unlimited instance of ThreadQueue
53 */
54 public ThreadQueue()
55 {
56 }
57
58 /***
59 * Creates a new instance of ThreadQueue, which will block if the amount of queued elements reaches the given limit
60 *
61 * @param limit
62 */
63 public ThreadQueue(int limit)
64 {
65 this._limit = limit;
66 }
67
68 /***
69 * Returns the current number of object in the queue
70 */
71 public synchronized int size()
72 {
73 return _list.size();
74 }
75
76 /***
77 * Sets the max size of this queue, adding new elements will block when the queue size would get bigger than the
78 * limit
79 *
80 * @param limit max amount of elements this queue can contain at one time
81 */
82 public void setLimit( int limit )
83 {
84 this._limit = limit;
85 }
86
87 /***
88 * @return the limit of this queue or -1 if no limit was set
89 */
90 public int getLimit()
91 {
92 return this._limit;
93 }
94
95 /***
96 * adds a new object to the end of the queue. At least one thread will be notified.
97 */
98 public synchronized void add( Runnable thread )
99 {
100 if ( _limit == -1 )
101 {
102 _list.add( thread );
103 }
104 else
105 {
106 while ( size() >= _limit )
107 {
108 try
109 {
110 wait();
111 }
112 catch ( InterruptedException e )
113 {
114
115 }
116 }
117
118 _list.add( thread );
119 }
120
121 notifyAll();
122 }
123
124 /***
125 * Removes the first object from the queue, blocking until one is available. Note that this method will never return
126 * null and could block forever.
127 */
128 public synchronized Runnable remove()
129 {
130 Runnable answer = removeNoWait();
131 if ( answer == null )
132 {
133 try
134 {
135 wait( _defaultTimeout );
136 }
137 catch ( InterruptedException e )
138 {
139 logger.log( Level.WARNING, "Thread was interrupted: ", e );
140 }
141 answer = removeNoWait();
142 }
143 return answer;
144 }
145
146 /***
147 * Removes the first object from the queue without blocking. This method will return immediately with an item from
148 * the queue or null.
149 *
150 * @return the first thread removed from the queue or null if the queue is empty
151 */
152 private synchronized Runnable removeNoWait()
153 {
154 Runnable result = null;
155
156 if ( !_list.isEmpty() )
157 {
158 result = (Runnable) _list.removeFirst();
159 notifyAll();
160 }
161
162 return result;
163 }
164 }