1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
package org.apache.xmlrpc.util; |
17 |
|
|
18 |
|
import java.util.ArrayList; |
19 |
|
import java.util.List; |
20 |
|
|
21 |
|
|
22 |
|
|
23 |
|
|
24 |
|
|
25 |
|
public class ThreadPool { |
26 |
|
|
27 |
|
|
28 |
|
public interface Task { |
29 |
|
|
30 |
|
|
31 |
|
|
32 |
|
void run() throws Throwable; |
33 |
|
} |
34 |
|
|
35 |
|
private class MyThread extends Thread { |
36 |
|
private boolean shuttingDown; |
37 |
|
private int numTasks; |
38 |
|
private Task task; |
39 |
|
MyThread() { |
40 |
205 |
super(threadGroup, threadGroup.getName() + "-" + num++); |
41 |
205 |
setDaemon(true); |
42 |
205 |
} |
43 |
|
synchronized void shutdown() { |
44 |
0 |
shuttingDown = true; |
45 |
0 |
notify(); |
46 |
0 |
} |
47 |
490 |
synchronized boolean isShuttingDown() { return shuttingDown; } |
48 |
|
synchronized void waitForNotification() { |
49 |
245 |
if (getTask() != null) { return; } |
50 |
|
try { |
51 |
245 |
wait(); |
52 |
0 |
} catch (InterruptedException e) { |
53 |
|
} |
54 |
40 |
} |
55 |
0 |
synchronized int getNumTasks() { return numTasks; } |
56 |
980 |
synchronized Task getTask() { return task; } |
57 |
|
synchronized void setTask(Task pTask) { |
58 |
490 |
task = pTask; |
59 |
490 |
if (task != null) { |
60 |
245 |
notify(); |
61 |
|
} |
62 |
490 |
} |
63 |
|
synchronized void runTask() { |
64 |
245 |
Task tsk = getTask(); |
65 |
245 |
if (tsk == null) { |
66 |
0 |
return; |
67 |
|
} |
68 |
245 |
++numTasks; |
69 |
|
Throwable t; |
70 |
|
try { |
71 |
245 |
tsk.run(); |
72 |
245 |
t = null; |
73 |
0 |
} catch (Throwable th) { |
74 |
0 |
t = th; |
75 |
|
} |
76 |
245 |
if (t == null) { |
77 |
245 |
repool(this); |
78 |
|
} else { |
79 |
0 |
discard(this); |
80 |
|
} |
81 |
245 |
} |
82 |
|
public void run() { |
83 |
695 |
while (!isShuttingDown()) { |
84 |
490 |
if (getTask() == null) { |
85 |
245 |
waitForNotification(); |
86 |
|
} else { |
87 |
245 |
runTask(); |
88 |
|
} |
89 |
|
} |
90 |
0 |
} |
91 |
|
} |
92 |
|
|
93 |
410 |
private final ThreadGroup threadGroup; |
94 |
|
private final int maxSize; |
95 |
154 |
private final List waitingThreads = new ArrayList(); |
96 |
154 |
private final List runningThreads = new ArrayList(); |
97 |
154 |
private final List waitingTasks = new ArrayList(); |
98 |
410 |
private int num; |
99 |
|
|
100 |
|
|
101 |
|
|
102 |
|
|
103 |
|
|
104 |
|
|
105 |
154 |
public ThreadPool(int pMaxSize, String pName) { |
106 |
154 |
maxSize = pMaxSize; |
107 |
154 |
threadGroup = new ThreadGroup(pName); |
108 |
154 |
} |
109 |
|
|
110 |
|
synchronized void discard(MyThread pThread) { |
111 |
0 |
pThread.shutdown(); |
112 |
0 |
if (!runningThreads.remove(pThread)) { |
113 |
0 |
throw new IllegalStateException("The list of running threads didn't contain the thread " + pThread.getName()); |
114 |
|
} |
115 |
0 |
} |
116 |
|
|
117 |
|
synchronized void repool(MyThread pThread) { |
118 |
245 |
if (maxSize != 0 && (runningThreads.size() + waitingThreads.size()) <= maxSize) { |
119 |
0 |
discard(pThread); |
120 |
245 |
} else if (waitingTasks.size() > 0) { |
121 |
0 |
pThread.setTask((Task) waitingTasks.remove(0)); |
122 |
|
} else { |
123 |
245 |
pThread.setTask(null); |
124 |
245 |
if (!runningThreads.remove(pThread)) { |
125 |
0 |
throw new IllegalStateException("The list of running threads didn't contain the thread " + pThread.getName()); |
126 |
|
} |
127 |
245 |
waitingThreads.add(pThread); |
128 |
|
} |
129 |
245 |
} |
130 |
|
|
131 |
|
|
132 |
|
|
133 |
|
|
134 |
|
|
135 |
|
|
136 |
|
|
137 |
|
public synchronized boolean startTask(Task pTask) { |
138 |
245 |
if (maxSize != 0 && (runningThreads.size() + waitingThreads.size()) >= maxSize) { |
139 |
0 |
return false; |
140 |
|
} |
141 |
|
MyThread t; |
142 |
245 |
if (waitingThreads.size() > 0) { |
143 |
40 |
t = (MyThread) waitingThreads.remove(waitingThreads.size()-1); |
144 |
|
} else { |
145 |
205 |
t = new MyThread(); |
146 |
205 |
t.start(); |
147 |
|
} |
148 |
245 |
runningThreads.add(t); |
149 |
245 |
t.setTask(pTask); |
150 |
245 |
return true; |
151 |
|
} |
152 |
|
|
153 |
|
|
154 |
|
|
155 |
|
|
156 |
|
|
157 |
|
|
158 |
|
public synchronized boolean addTask(Task pTask) { |
159 |
0 |
if (startTask(pTask)) { |
160 |
0 |
return true; |
161 |
|
} |
162 |
0 |
waitingTasks.add(pTask); |
163 |
0 |
return false; |
164 |
|
} |
165 |
|
|
166 |
|
|
167 |
|
|
168 |
|
public synchronized void shutdown() { |
169 |
0 |
for (int i = 0; i < waitingThreads.size(); i++) { |
170 |
0 |
MyThread t = (MyThread) waitingThreads.get(i); |
171 |
0 |
t.shutdown(); |
172 |
|
} |
173 |
0 |
for (int i = 0; i < runningThreads.size(); i++) { |
174 |
0 |
MyThread t = (MyThread) runningThreads.get(i); |
175 |
0 |
t.shutdown(); |
176 |
|
} |
177 |
0 |
} |
178 |
|
|
179 |
|
|
180 |
|
|
181 |
|
|
182 |
0 |
public int getMaxThreads() { return maxSize; } |
183 |
|
} |