KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snmp4j > util > ThreadPool


1 /*_############################################################################
2   _##
3   _## SNMP4J - ThreadPool.java
4   _##
5   _## Copyright 2003-2007 Frank Fock and Jochen Katz (SNMP4J.org)
6   _##
7   _## Licensed under the Apache License, Version 2.0 (the "License");
8   _## you may not use this file except in compliance with the License.
9   _## You may obtain a copy of the License at
10   _##
11   _## http://www.apache.org/licenses/LICENSE-2.0
12   _##
13   _## Unless required by applicable law or agreed to in writing, software
14   _## distributed under the License is distributed on an "AS IS" BASIS,
15   _## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   _## See the License for the specific language governing permissions and
17   _## limitations under the License.
18   _##
19   _##########################################################################*/

20
21 package org.snmp4j.util;
22
23 import java.util.*;
24
25 /**
26  * The <code>ThreadPool</code> provides a pool of a fixed number of threads
27  * that are capable to execute tasks that implement the <code>Runnable</code>
28  * interface concurrently. The ThreadPool blocks when all threads are busy
29  * with tasks and an additional task is added.
30  *
31  * @author Frank Fock
32  * @version 1.6
33  * @since 1.0.2
34  */

35 public class ThreadPool {
36
37   protected Vector taskManagers;
38   protected String JavaDoc name = "ThreadPool";
39   protected volatile boolean stop = false;
40   protected boolean respawnThreads = false;
41
42   protected ThreadPool() {
43   }
44
45   protected String JavaDoc getTaskManagerName(String JavaDoc prefix, int index) {
46     return prefix+"."+index;
47   }
48
49   protected void setup(String JavaDoc name, int size) {
50     this.name = name;
51     taskManagers = new Vector(size);
52     for (int i=0; i<size; i++) {
53       TaskManager tm = new TaskManager(getTaskManagerName(name, i));
54       taskManagers.add(tm);
55       tm.start();
56     }
57   }
58
59   /**
60    * Creates a thread pool with the supplied name and size.
61    * @param name
62    * the name prefix for the threads in this pool.
63    * @param size
64    * the number of threads in this pool. This number also specifies the
65    * number of concurrent tasks that can be executed with this pool.
66    * @return
67    * a <code>ThreadPool</code> instance.
68    */

69   public static ThreadPool create(String JavaDoc name, int size) {
70     ThreadPool pool = new ThreadPool();
71     pool.setup(name, size);
72     return pool;
73   }
74
75   /**
76    * Executes a task on behalf of this thread pool. If all threads are currently
77    * busy, this method call blocks until a thread gets idle again which is when
78    * the call returns immediately.
79    * @param task
80    * a <code>Runnable</code> to execute.
81    */

82   public synchronized void execute(Runnable JavaDoc task) {
83     while (true) {
84       for (int i=0; i<taskManagers.size(); i++) {
85         TaskManager tm = (TaskManager) taskManagers.get(i);
86         if ((respawnThreads) && (!tm.isAlive())) {
87           tm = new TaskManager(getTaskManagerName(name, i));
88         }
89         if (tm.isIdle()) {
90           tm.execute(task);
91           return;
92         }
93       }
94       try {
95         wait();
96       }
97       catch (InterruptedException JavaDoc ex) {
98         // ignore
99
}
100     }
101   }
102
103   /**
104    * Tries to execute a task on behalf of this thread pool. If all threads are
105    * currently busy, this method returns <code>false</code>. Otherwise the task
106    * is executed in background.
107    * @param task
108    * a <code>Runnable</code> to execute.
109    * @return
110    * <code>true</code> if the task is executing.
111    * @since 1.6
112    */

113   public synchronized boolean tryToExecute(Runnable JavaDoc task) {
114     for (int i=0; i<taskManagers.size(); i++) {
115       TaskManager tm = (TaskManager) taskManagers.get(i);
116       if ((respawnThreads) && (!tm.isAlive())) {
117         tm = new TaskManager(getTaskManagerName(name, i));
118       }
119       if (tm.isIdle()) {
120         tm.execute(task);
121         return true;
122       }
123     }
124     return false;
125   }
126
127   /**
128    * Tests if the threads are respawn (recreates) when they have been stopped
129    * or canceled.
130    * @return
131    * <code>true</code> if threads are respawn.
132    */

133   public boolean isRespawnThreads() {
134     return respawnThreads;
135   }
136
137   /**
138    * Specifies whether threads are respawned by this thread pool after they
139    * have been stopped or not. Default is no respawning.
140    * @param respawnThreads
141    * if <code>true</code> then threads will be respawn.
142    */

143   public void setRespawnThreads(boolean respawnThreads) {
144     this.respawnThreads = respawnThreads;
145   }
146
147   /**
148    * Returns the name of the thread pool.
149    * @return
150    * the name of this thread pool.
151    */

152   public String JavaDoc getName() {
153     return name;
154   }
155
156   /**
157    * Stops all threads in this thread pool gracefully. This method will not
158    * return until all threads have been terminated and joined successfully.
159    */

160   public void stop() {
161     List tms;
162     synchronized (this) {
163       stop = true;
164       tms = (List) taskManagers.clone();
165     }
166     for (int i=0; i<tms.size(); i++) {
167       TaskManager tm = (TaskManager) tms.get(i);
168       tm.terminate();
169       synchronized (tm) {
170         tm.notify();
171       }
172       try {
173         tm.join();
174       }
175       catch (InterruptedException JavaDoc ex) {
176         //ignore
177
}
178     }
179   }
180
181   /**
182    * Cancels all threads non-blocking by interrupting them.
183    */

184   public synchronized void cancel() {
185     stop = true;
186     for (int i=0; i<taskManagers.size(); i++) {
187       TaskManager tm = (TaskManager) taskManagers.get(i);
188       tm.terminate();
189       tm.interrupt();
190     }
191   }
192
193   /**
194    * Interrupts all threads in the pool.
195    * @since 1.6
196    */

197   public synchronized void interrupt() {
198     for (int i=0; i<taskManagers.size(); i++) {
199       TaskManager tm = (TaskManager) taskManagers.get(i);
200       tm.interrupt();
201     }
202   }
203
204   /**
205    * Checks if all threads of the pool are idle.
206    * @return
207    * <code>true</code> if all threads are idle.
208    * @since 1.6
209    */

210   public synchronized boolean isIdle() {
211     for (int i=0; i<taskManagers.size(); i++) {
212       TaskManager tm = (TaskManager) taskManagers.get(i);
213       if (!tm.isIdle()) {
214         return false;
215       }
216     }
217     return true;
218   }
219
220   /**
221    * The <code>TaskManager</code> executes tasks in a thread.
222    *
223    * @author Frank Fock
224    * @version 1.6
225    * @since 1.0.2
226    */

227   class TaskManager extends Thread JavaDoc {
228
229     private Runnable JavaDoc task = null;
230     private volatile boolean run = true;
231
232     public TaskManager(String JavaDoc name) {
233       super(name);
234     }
235
236     public synchronized void run() {
237       while ((!stop) && run) {
238         if (task != null) {
239           task.run();
240           synchronized (ThreadPool.this) {
241             task = null;
242             ThreadPool.this.notify();
243           }
244         }
245         else {
246           try {
247             wait();
248           }
249           catch (InterruptedException JavaDoc ex) {
250             run = respawnThreads;
251             break;
252           }
253         }
254       }
255     }
256
257     public boolean isIdle() {
258       return ((task == null) && run);
259     }
260
261     public boolean isStopped() {
262       return stop;
263     }
264
265     public void terminate() {
266       stop = true;
267     }
268
269     public synchronized void execute(Runnable JavaDoc task) {
270       if (this.task == null) {
271         this.task = task;
272         notify();
273       }
274       else {
275         throw new IllegalStateException JavaDoc("TaskManager is not idle");
276       }
277     }
278   }
279 }
280
Popular Tags