KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mx > util > ThreadPool


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7
8 package org.jboss.mx.util;
9
10 import java.util.Stack JavaDoc;
11
12 /**
13  * A simple thread pool. Idle threads are cached for future use.
14  * The cache grows until it reaches a maximum size (default 10).
15  * When there is nothing in the cache, a new thread is created.
16  * By default the threads are daemon threads.
17  *
18  * <a HREF="mailto:rickard.oberg@telkel.com">Rickard Öberg</a>
19  * <a HREF="mailto:adrian.brock@happeningtimes.com">Adrian Brock</a>
20  * @version $Revision: 1.6 $
21  */

22 public class ThreadPool
23 {
24   // Constants -----------------------------------------------------
25

26   // Attributes ----------------------------------------------------
27
private static int counter = 0;
28
29   /**
30    * Stack of idle threads cached for future use.
31    */

32   private Stack JavaDoc pool = new Stack JavaDoc();
33
34   /**
35    * Maximum number of idle threads cached in this pool.
36    */

37   private int maxSize = 10;
38
39   /**
40    * Is the thread pool active
41    */

42   private boolean active = false;
43
44   /**
45    * Whether the threads are daemon threads.
46    */

47   private boolean daemon = true;
48
49   // Static --------------------------------------------------------
50

51   // Constructors --------------------------------------------------
52

53   /**
54    * Create a new pool.
55    */

56   public ThreadPool()
57   {
58   }
59
60   /**
61    * Create a new pool with an activity status
62    *
63    * @param active true for active, false otherwise
64    */

65   public ThreadPool(boolean active)
66   {
67      this.active = active;
68   }
69
70   // Public --------------------------------------------------------
71

72   /**
73    * Set the maximum number of idle threads cached in this pool.
74    *
75    * @param size the new maximum size.
76    */

77   public void setMaximumSize(int size)
78   {
79     maxSize = size;
80   }
81
82   /**
83    * Get the maximum number of idle threads cached in this pool.
84    *
85    * @return the maximum size
86    */

87   public int getMaximumSize()
88   {
89     return maxSize;
90   }
91
92   /**
93    * Set the activity status of the pool. Setting the pool to
94    * inactive, clears the pool.
95    *
96    * @param status pass true for active, false otherwise.
97    */

98   public void setActive(boolean status)
99   {
100     active = status;
101     if (active == false)
102       while (pool.size() > 0)
103         ((Worker)pool.pop()).die();
104   }
105
106   /**
107    * Get the activity status of the pool.
108    *
109    * @return true for an active pool, false otherwise.
110    */

111   public boolean isActive()
112   {
113     return active;
114   }
115
116   /**
117    * Set whether new threads are daemon threads.
118    *
119    * @param value pass true for daemon threads, false otherwise.
120    */

121   public void setDaemonThreads(boolean value)
122   {
123     daemon = value;
124   }
125
126   /**
127    * Get whether new threads are daemon threads.
128    *
129    * @return true for daemon threads, false otherwise.
130    */

131   public boolean getDaemonThreads()
132   {
133     return daemon;
134   }
135
136   /**
137    * Do some work.
138    * This will either create a new thread to do the work, or
139    * use an existing idle cached thread.
140    *
141    * @param work the work to perform.
142    */

143    public synchronized void run(Runnable JavaDoc work)
144    {
145      if (pool.size() == 0)
146        new Worker(work);
147      else
148      {
149        Worker worker = (Worker) pool.pop();
150        worker.run(work);
151      }
152    }
153
154    // Private -------------------------------------------------------
155

156    /**
157     * Put an idle worker thread back in the pool of cached idle threads.
158     * This is called from the worker thread itself. When the cache is
159     * full, the thread is discarded.
160     *
161     * @param worker the worker to return.
162     */

163    private synchronized void returnWorker(Worker worker)
164    {
165      if (pool.size() < maxSize)
166        pool.push(worker);
167      else
168        worker.die();
169    }
170
171    // Inner classes -------------------------------------------------
172

173   /**
174    * A worker thread runs a worker.
175    */

176   class Worker extends Thread JavaDoc
177   {
178     /**
179      * Flags that this worker may continue to work.
180      */

181     boolean running = true;
182
183     /**
184      * Work to do, of <code>null</code> if no work to do.
185      */

186     Runnable JavaDoc work;
187
188     /**
189     * Create a new Worker to do some work.
190     *
191     * @param work the work to perform
192     */

193     Worker(Runnable JavaDoc work)
194     {
195        // give it a thread so we can figure out what this thread is in debugging
196
super("ThreadPoolWorker["+(++counter)+"]");
197       this.work = work;
198       setDaemon(daemon);
199       start();
200     }
201
202     /**
203      * Tell this worker to die.
204      */

205     public synchronized void die()
206     {
207       running = false;
208       this.notify();
209     }
210
211     /**
212      * Give this Worker some work to do.
213      *
214      * @param the work to perform.
215      * @throws IllegalStateException If this worker already
216      * has work to do.
217      */

218     public synchronized void run(Runnable JavaDoc work)
219     {
220       if (this.work != null)
221         throw new IllegalStateException JavaDoc("Worker already has work to do.");
222       this.work = work;
223       this.notify();
224     }
225
226     /**
227      * The worker loop.
228      */

229     public void run()
230     {
231       while (active && running)
232       {
233         // If work is available then execute it
234
if (work != null)
235         {
236           try
237           {
238             work.run();
239           }
240           catch (Exception JavaDoc ignored) {}
241
242           // Clear work
243
work = null;
244         }
245                 
246         // Return to pool of cached idle threads
247
returnWorker(this);
248
249         // Wait for more work to become available
250
synchronized (this)
251         {
252           while (running && work == null)
253           {
254             try
255             {
256               this.wait();
257             }
258             catch (InterruptedException JavaDoc ignored) {}
259           }
260         }
261       }
262     }
263   }
264 }
265
Popular Tags