01: // $Id: ThreadPool.java,v 1.9 2005/07/17 11:33:58 chrislott Exp $
02:
03: package org.jgroups.util;
04:
05: import org.apache.commons.logging.Log;
06: import org.apache.commons.logging.LogFactory;
07:
08: /**
09: * Maintains a set of ReusableThreads. When a thread is to be returned, all existing threads
10: * are checked: when one is available, it will be returned. Otherwise, a new thread is created
11: * and returned, unless the pool limit is reached, in which case <code>null</code> is returned.
12: * Creates threads only as needed, up to the MAX_NUM limit. However, does not shrink the pool
13: * when more threads become available than are used.
14: * @todo Shrink thread pool if threads are unused after some configurable time.
15: * @author Bela Ban
16: */
17: public class ThreadPool {
18: int MAX_NUM = 255;
19: int current_index = 0; /// next available thread
20: ReusableThread[] pool = null;
21: boolean[] available_threads = null;
22: protected static final Log log = LogFactory
23: .getLog(ThreadPool.class);
24:
25: public ThreadPool(int max_num) {
26: MAX_NUM = max_num;
27: pool = new ReusableThread[MAX_NUM];
28: available_threads = new boolean[MAX_NUM];
29: for (int i = 0; i < pool.length; i++) {
30: pool[i] = null;
31: available_threads[i] = true;
32: }
33: if (log.isDebugEnabled())
34: log.debug("created a pool of " + MAX_NUM + " threads");
35: }
36:
37: public ReusableThread getThread() {
38: ReusableThread retval = null, tmp;
39:
40: synchronized (pool) {
41: // check whether a previously created thread can be reused
42: for (int i = 0; i < current_index; i++) {
43: tmp = pool[i];
44: if (tmp.available()) {
45: return tmp;
46: }
47: }
48:
49: // else create a new thread and add it to the pool
50: if (current_index >= MAX_NUM) {
51: if (log.isErrorEnabled())
52: log.error("could not create new thread because "
53: + "pool's max size reached (" + MAX_NUM
54: + ") !");
55: return null;
56: } else {
57: retval = new ReusableThread();
58: pool[current_index++] = retval;
59: return retval;
60: }
61: }
62:
63: }
64:
65: public void destroy() {
66: deletePool();
67: }
68:
69: public String toString() {
70: StringBuffer ret = new StringBuffer();
71:
72: synchronized (pool) {
73: ret.append("ThreadPool: capacity=" + pool.length
74: + ", index=" + current_index + '\n');
75: ret.append("Threads are:\n");
76: for (int i = 0; i < current_index; i++)
77: ret.append("[" + i + ": " + pool[i] + "]\n");
78: }
79: return ret.toString();
80: }
81:
82: void deletePool() {
83: ReusableThread t;
84: synchronized (pool) {
85: for (int i = 0; i < MAX_NUM; i++) {
86: t = pool[i];
87: if (t != null) {
88: t.stop();
89: pool[i] = null;
90: }
91: }
92: current_index = 0;
93: }
94: }
95:
96: }
|