View Javadoc

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                     // do nothing
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 }