KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jsmtpd > generic > threadpool > GenericThreadPool


1 /*
2  *
3  * Jsmtpd, Java SMTP daemon
4  * Copyright (C) 2005 Jean-Francois POUX, jf.poux@laposte.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  */

21 package org.jsmtpd.generic.threadpool;
22
23 import java.util.Iterator JavaDoc;
24 import java.util.LinkedList JavaDoc;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 /**
30  * A generic, fixed-size thread pooler
31  * each not busy thread are kept waiting
32  *
33  * Things to do to add auto-grow ability :
34  * Record number of active th over time (at each assign free th, or a controling thread)
35  * if thread pool is inactive during a while, and curent size is bigger than min size,
36  * try to remove free thds from the pool. => synchronize the collection
37  *
38  *
39  * Add a max thread int
40  * add min thread int
41  *
42  *
43  * Instead of throwing an exception directly when pool is exhausted
44  * try to increase by 10% the number of thd, if under max th., then re assign a thread.
45  *
46  *
47  *
48  * @author Jean-Francois POUX
49  * @see org.jsmtpd.generic.threadpool.IThreadedClass
50  */

51 public class GenericThreadPool implements ThreadPool {
52     private Log log = LogFactory.getLog(GenericThreadPool.class);
53     private LinkedList JavaDoc<ThreadWorker> threads = new LinkedList JavaDoc<ThreadWorker>();
54
55     /**
56      *
57      * @param numThreads number of threads to be spawned
58      * @param threadClassName name of the class to be threaded, must impletement IThreadedClass
59      * @throws InstantiationException
60      * @throws IllegalAccessException
61      * @throws ClassNotFoundException
62      */

63     public GenericThreadPool(int numThreads, String JavaDoc threadClassName,String JavaDoc displayThreadName) throws InstantiationException JavaDoc, IllegalAccessException JavaDoc, ClassNotFoundException JavaDoc {
64         ThreadWorker tmp;
65         IThreadedClass cls;
66         log.debug("Starting a fixed pool of "+numThreads+" threads");
67         for (int i = 0; i < numThreads; i++) {
68             tmp = new ThreadWorker();
69             cls = (IThreadedClass) Class.forName(threadClassName).newInstance();
70             tmp.setWorker(cls);
71             tmp.setName(displayThreadName+"#"+tmp.getId());
72             tmp.start();
73             while (!tmp.isFree()) {
74                 //wait for thread to be up
75
Thread.yield();
76                 log.debug("Thread "+tmp.getName()+" ready");
77             }
78             threads.add(tmp);
79         }
80     }
81
82     /**
83      * Will gracefully shutdown each running thread
84      *
85      */

86     public void gracefullShutdown() {
87         log.debug("Gracefull shutdown ...");
88         ThreadWorker tmp;
89         for (int i = 0; i < threads.size(); i++) {
90             tmp = (ThreadWorker) threads.get(i);
91             tmp.gracefullShutdown();
92         }
93     }
94
95     /**
96      * Will force each thread to shutdown
97      *
98      */

99     public void forceShutdown() {
100         log.debug("Forcing shutdown ...");
101         ThreadWorker tmp;
102         for (int i = 0; i < threads.size(); i++) {
103             tmp = (ThreadWorker) threads.get(i);
104             tmp.forceShutdown();
105         }
106     }
107
108     /**
109      *
110      * @return true if any free thread
111      */

112     public synchronized boolean hasFreeThread() {
113         for (Iterator JavaDoc iter = threads.iterator(); iter.hasNext();) {
114             ThreadWorker element = (ThreadWorker) iter.next();
115             if (element.isFree())
116                 return true;
117         }
118         return false;
119     }
120
121     /**
122      *
123      */

124     public synchronized int countFreeThread() {
125         int count = 0;
126         for (Iterator JavaDoc iter = threads.iterator(); iter.hasNext();) {
127             ThreadWorker element = (ThreadWorker) iter.next();
128             if (element.isFree())
129                 count++;
130         }
131         return count;
132     }
133
134     /**
135      * passes the obj parameter to the thread instance, and runs its doJob mehtod
136      * @param obj the object to pass
137      * @throws BusyThreadPoolException when the pool is exhausted
138      */

139     public synchronized void assignFreeThread(Object JavaDoc obj) throws BusyThreadPoolException {
140         int i = 0;
141         for (Iterator JavaDoc iter = threads.iterator(); iter.hasNext();) {
142             ThreadWorker element = (ThreadWorker) iter.next();
143             if (element.isFree()) {
144                 log.debug("Worker "+element.getName()+" is free, assigning job");
145                 element.setParam(obj);
146                 element.wake();
147                 return;
148             }
149             i++;
150         }
151         log.warn("Thread pool exhausted !");
152         throw new BusyThreadPoolException();
153     }
154
155 }
Popular Tags