1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the Apache Public Source License 2.0 ("the License").
3 // You may not use this file except in compliance with the License.
12 * - Attempting to add a task will block until the task is assigned to
14 * - If a task has not been assigned after MINIMUM_DISPATCH_DELAY, a new
15 * thread (above and beyond the ThreadPool size) will be created to
17 * - Whenever at least minIdleThreads are idle and more than minThreads
18 * threads exist overall, any threads which complete their task will
22 public final class ThreadPool {
24 private static final int MINIMUM_DISPATCH_DELAY = 1000;
25 private static final int minIdleThreads = 3;
27 private final int minThreads;
28 private int numThreads;
29 private final PooledThread[] idleThreads;
30 private int numIdleThreads;
32 public ThreadPool(int minThreads) {
33 this.minThreads = minThreads;
35 this.numIdleThreads = 0;
36 this.idleThreads = new PooledThread[minThreads];
37 for(int i=0; i<this.idleThreads.length; i++)
41 public synchronized void start(Runnable r) {
42 /* if no idle threads, wait for MINIMUM_DISPATCH_DELAY or until notified */
43 if (numIdleThreads == 0) try {
44 this.wait(MINIMUM_DISPATCH_DELAY);
45 } catch (Exception e) { Log.error(this, e); }
47 /* if there are idle threads, use one */
48 if (numIdleThreads > 0) {
50 idleThreads[numIdleThreads].start(r);
51 idleThreads[numIdleThreads] = null;
55 /* otherwise, create a new thread */
56 new PooledThread().start(r);
59 private class PooledThread extends Thread {
60 private Runnable runnable = null;
61 public PooledThread() {
62 synchronized(ThreadPool.this) { numThreads++; }
65 public synchronized void start(Runnable runnable) {
66 if (this.runnable != null)
67 throw new Error("start() on a thread that is alread busy!");
68 this.runnable = runnable;
76 synchronized(ThreadPool.this) {
77 /* if the idle array is full, just let ourselves die */
78 if (numIdleThreads > minIdleThreads && numThreads > minThreads) return;
79 /* otherwise put ourselves back in the pool and release anybody who is waiting */
80 idleThreads[numIdleThreads++] = this;
81 ThreadPool.this.notifyAll();
85 synchronized(this) { while (runnable==null) wait(); }
87 } catch (Exception e) { Log.error(this, e); }
91 synchronized(ThreadPool.this) {