KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > util > ThreadPool


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.util;
13
14 import java.util.LinkedList JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.HashSet JavaDoc;
17
18 /**
19  * Simple pool of Threads.
20  */

21 public class ThreadPool {
22
23     private String JavaDoc name;
24     private HashSet JavaDoc active = new HashSet JavaDoc();
25     private LinkedList JavaDoc idle = new LinkedList JavaDoc();
26     private int idleCount;
27     private int maxActive = 10;
28     private int maxIdle = 3;
29     private int lastThreadId;
30     private boolean closed;
31
32     public ThreadPool(String JavaDoc name) {
33         this.name = name;
34     }
35
36     public int getMaxActive() {
37         return maxActive;
38     }
39
40     public void setMaxActive(int maxActive) {
41         this.maxActive = maxActive;
42     }
43
44     public int getMaxIdle() {
45         return maxIdle;
46     }
47
48     public void setMaxIdle(int maxIdle) {
49         this.maxIdle = maxIdle;
50     }
51
52     public synchronized int getActiveCount() {
53         return active.size();
54     }
55
56     public synchronized int getIdleCount() {
57         return idleCount;
58     }
59
60     /**
61      * Close the pool, stopping all threads. This does not wait for the
62      * threads to actually stop before returning. This is a NOP if the
63      * pool has already been closed.
64      */

65     public synchronized void close() {
66         if (closed) {
67             return;
68         }
69         closed = true;
70         for (Iterator JavaDoc i = idle.iterator(); i.hasNext(); ) {
71             Worker w = (Worker)i.next();
72             w.terminate();
73         }
74         idle = null;
75         idleCount = 0;
76         for (Iterator JavaDoc i = active.iterator(); i.hasNext(); ) {
77             Worker w = (Worker)i.next();
78             w.terminate();
79         }
80         active = null;
81     }
82
83     /**
84      * Executed runnable using a Thread from the pool. This will block for
85      * timeoutMs and forever if this is 0. Returns true if the task is
86      * being executed (i.e. a Thread was available) or false if not (i.e.
87      * pool full).
88      */

89     public synchronized boolean execute(Runnable JavaDoc runnable, int timeoutMs) {
90         if (closed) {
91             throw new IllegalStateException JavaDoc("Pool has been closed");
92         }
93         Worker t;
94         if (idleCount == 0) {
95             for (; isFull(); ) {
96                 try {
97                     wait(timeoutMs);
98                     if (isFull()) {
99                         return false;
100                     }
101                 } catch (InterruptedException JavaDoc e) {
102                     // ignore
103
}
104             }
105             t = new Worker();
106         } else {
107             t = (Worker)idle.removeFirst();
108             --idleCount;
109         }
110         active.add(t);
111         t.execute(runnable);
112         return true;
113     }
114
115     protected boolean isFull() {
116         return active.size() >= maxActive;
117     }
118
119     private synchronized void finishedWork(Worker t) {
120         if (!closed) {
121             active.remove(t);
122             if (idleCount >= maxIdle) {
123                 t.terminate();
124             } else {
125                 idle.addLast(t);
126                 ++idleCount;
127             }
128         }
129     }
130
131     private class Worker extends Thread JavaDoc {
132
133         private boolean stopFlag;
134         private Runnable JavaDoc runnable;
135
136         public Worker() {
137             super(name + " " + ++lastThreadId);
138             setDaemon(true);
139         }
140
141         /**
142          * Executed runnable.
143          */

144         public void execute(Runnable JavaDoc runnable) {
145             this.runnable = runnable;
146             if (!isAlive()) {
147                 start();
148             } else {
149                 synchronized (this) {
150                     notify();
151                 }
152             }
153         }
154
155         /**
156          * Stop this thread as soon as possible.
157          */

158         public void terminate() {
159             stopFlag = true;
160             interrupt();
161         }
162
163         public void run() {
164             for (; !stopFlag; ) {
165                 try {
166                     runnable.run();
167                 } catch (Throwable JavaDoc e) {
168                     if (e instanceof ThreadDeath JavaDoc) {
169                         throw (ThreadDeath JavaDoc)e;
170                     }
171                 }
172                 runnable = null;
173                 finishedWork(this);
174                 if (stopFlag) break;
175                 synchronized (this) {
176                     try {
177                         wait();
178                     } catch (InterruptedException JavaDoc e) {
179                         // ignore
180
}
181                 }
182             }
183         }
184
185     }
186
187 }
188
189
Popular Tags