139 |
|
* @spec JSR-166 |
140 |
|
* @revised $Date$ |
141 |
|
* @editor $Author$ |
142 |
< |
* |
142 |
> |
* @author Doug Lea |
143 |
|
*/ |
144 |
|
public class ThreadPoolExecutor implements ExecutorService { |
145 |
|
/** |
197 |
|
private volatile int shutdownStatus; |
198 |
|
|
199 |
|
// Special values for status |
200 |
+ |
/** Normal, not-shutdown mode */ |
201 |
|
private static final int NOT_SHUTDOWN = 0; |
202 |
+ |
/** Controlled shutdown mode */ |
203 |
|
private static final int SHUTDOWN_WHEN_IDLE = 1; |
204 |
+ |
/*8 Immediate shutdown mode */ |
205 |
|
private static final int SHUTDOWN_NOW = 2; |
206 |
|
|
207 |
|
/** |
230 |
|
*/ |
231 |
|
private long completedTaskCount; |
232 |
|
|
233 |
+ |
/** |
234 |
+ |
* The default thread facotry |
235 |
+ |
*/ |
236 |
|
private static final ThreadFactory defaultThreadFactory = |
237 |
|
new ThreadFactory() { |
238 |
|
public Thread newThread(Runnable r) { |
240 |
|
} |
241 |
|
}; |
242 |
|
|
243 |
+ |
/** |
244 |
+ |
* The default rejectect execution handler |
245 |
+ |
*/ |
246 |
|
private static final RejectedExecutionHandler defaultHandler = |
247 |
|
new AbortPolicy(); |
248 |
|
|
249 |
|
/** |
250 |
|
* Create and return a new thread running firstTask as its first |
251 |
|
* task. Call only while holding mainLock |
252 |
+ |
* @param firstTask the task the new thread should run first (or |
253 |
+ |
* null if none) |
254 |
+ |
* @return the new thread |
255 |
|
*/ |
256 |
|
private Thread addThread(Runnable firstTask) { |
257 |
|
Worker w = new Worker(firstTask); |
267 |
|
/** |
268 |
|
* Create and start a new thread running firstTask as its first |
269 |
|
* task, only if less than corePoolSize threads are running. |
270 |
+ |
* @param firstTask the task the new thread should run first (or |
271 |
+ |
* null if none) |
272 |
|
* @return true if successful. |
273 |
|
*/ |
274 |
< |
boolean addIfUnderCorePoolSize(Runnable task) { |
274 |
> |
boolean addIfUnderCorePoolSize(Runnable firstTask) { |
275 |
|
Thread t = null; |
276 |
|
mainLock.lock(); |
277 |
|
try { |
278 |
|
if (poolSize < corePoolSize) |
279 |
< |
t = addThread(task); |
279 |
> |
t = addThread(firstTask); |
280 |
|
} |
281 |
|
finally { |
282 |
|
mainLock.unlock(); |
291 |
|
* Create and start a new thread only if less than maximumPoolSize |
292 |
|
* threads are running. The new thread runs as its first task the |
293 |
|
* next task in queue, or if there is none, the given task. |
294 |
+ |
* @param firstTask the task the new thread should run first (or |
295 |
+ |
* null if none) |
296 |
|
* @return null on failure, else the first task to be run by new thread. |
297 |
|
*/ |
298 |
< |
private Runnable addIfUnderMaximumPoolSize(Runnable task) { |
298 |
> |
private Runnable addIfUnderMaximumPoolSize(Runnable firstTask) { |
299 |
|
Thread t = null; |
300 |
|
Runnable next = null; |
301 |
|
mainLock.lock(); |
303 |
|
if (poolSize < maximumPoolSize) { |
304 |
|
next = workQueue.poll(); |
305 |
|
if (next == null) |
306 |
< |
next = task; |
306 |
> |
next = firstTask; |
307 |
|
t = addThread(next); |
308 |
|
} |
309 |
|
} |
319 |
|
|
320 |
|
/** |
321 |
|
* Get the next task for a worker thread to run. |
322 |
+ |
* @return the task |
323 |
+ |
* @throws InterruptedException if interrupted while waiting for task |
324 |
|
*/ |
325 |
|
private Runnable getTask() throws InterruptedException { |
326 |
|
for (;;) { |
345 |
|
|
346 |
|
/** |
347 |
|
* Perform bookkeeping for a terminated worker thread. |
348 |
+ |
* @param w the worker |
349 |
|
*/ |
350 |
|
private void workerDone(Worker w) { |
351 |
|
boolean allDone = false; |
666 |
|
* |
667 |
|
* @param command the task to execute |
668 |
|
* @throws RejectedExecutionException at discretion of |
669 |
< |
* <tt>RejectedExecutionHandler</tt>, if task cannot be accepted for execution |
669 |
> |
* <tt>RejectedExecutionHandler</tt>, if task cannot be accepted |
670 |
> |
* for execution |
671 |
|
*/ |
672 |
|
public void execute(Runnable command) { |
673 |
|
for (;;) { |
788 |
|
* causing it not to be run if it has not already started. This |
789 |
|
* method may be useful as one part of a cancellation scheme. |
790 |
|
* |
791 |
< |
* #return true if the task was removed |
791 |
> |
* @param task the task to remove |
792 |
> |
* @return true if the task was removed |
793 |
|
*/ |
794 |
|
public boolean remove(Runnable task) { |
795 |
|
return getQueue().remove(task); |
825 |
|
* they next become idle. |
826 |
|
* |
827 |
|
* @param corePoolSize the new core size |
828 |
< |
* @throws IllegalArgumentException if <tt>corePoolSize</tt> less than zero |
828 |
> |
* @throws IllegalArgumentException if <tt>corePoolSize</tt> |
829 |
> |
* less than zero |
830 |
|
*/ |
831 |
|
public void setCorePoolSize(int corePoolSize) { |
832 |
|
if (corePoolSize < 0) |
1076 |
|
} |
1077 |
|
|
1078 |
|
/** |
1079 |
< |
* A handler for unexecutable tasks that throws a <tt>RejectedExecutionException</tt>. |
1079 |
> |
* A handler for unexecutable tasks that throws a |
1080 |
> |
* <tt>RejectedExecutionException</tt>. |
1081 |
|
*/ |
1082 |
|
public static class AbortPolicy implements RejectedExecutionHandler { |
1083 |
|
|
1129 |
|
} |
1130 |
|
|
1131 |
|
/** |
1132 |
< |
* A handler for unexecutable tasks that discards the oldest unhandled request. |
1132 |
> |
* A handler for unexecutable tasks that discards the oldest |
1133 |
> |
* unhandled request. |
1134 |
|
*/ |
1135 |
|
public static class DiscardOldestPolicy implements RejectedExecutionHandler { |
1136 |
|
/** |