added ThreadPool class
authoradam <adam@megacz.com>
Fri, 18 Mar 2005 09:11:41 +0000 (09:11 +0000)
committeradam <adam@megacz.com>
Fri, 18 Mar 2005 09:11:41 +0000 (09:11 +0000)
darcs-hash:20050318091141-5007d-03d815051e82d3328d2b93a1da5fe7fa0678850f.gz

src/org/ibex/util/ThreadPool.java [new file with mode: 0644]

diff --git a/src/org/ibex/util/ThreadPool.java b/src/org/ibex/util/ThreadPool.java
new file mode 100644 (file)
index 0000000..30e490f
--- /dev/null
@@ -0,0 +1,75 @@
+// Copyright 2000-2005 the Contributors, as shown in the revision logs.
+// Licensed under the Apache Public Source License 2.0 ("the License").
+// You may not use this file except in compliance with the License.
+
+package org.ibex.util;
+
+import java.io.*;
+
+/** A simple thread pool. */
+public final class ThreadPool {
+
+    private final Queue tasks;
+    private final Queue idle;
+    private final int   minThreads;
+    private final int   maxThreads;
+    private       int   numThreads;
+
+    public ThreadPool(int min, int max) {
+        this.minThreads  = min;
+        this.maxThreads  = max;
+        this.idle    = new Queue(Math.min(min, 100));
+        this.tasks   = new Queue(Math.min(max, 100));
+    }
+
+    public synchronized void appendTask(Runnable r) {
+        if (idle.size() > 0)              ((PooledThread)idle.remove()).setTask(r);
+        else if (numThreads < maxThreads) new PooledThread(r);
+        else                              tasks.append(r);
+    }
+
+    public synchronized void prependTask(Runnable r) {
+        if (idle.size() > 0)              ((PooledThread)idle.remove()).setTask(r);
+        else if (numThreads < maxThreads) new PooledThread(r);
+        else                              tasks.prepend(r);
+    }
+
+    private class PooledThread extends Thread {
+        private Runnable task = null;
+        private boolean die = false;
+        public PooledThread(Runnable r) {
+            numThreads++;
+            if (r!=null) setTask(r);
+            start();
+        }
+        public synchronized boolean isRunning() { return task != null; }
+        public synchronized boolean setTask(Runnable r) {
+            if (task != null) throw new Error("setTask() on a thread that is alread busy!");
+            task = r;
+            notifyAll();
+            return true;
+        }
+        private synchronized void recycle() {
+            task = null;
+            // depends on the fact that our Queue class is synchronized
+            if (tasks.size() > 0)                       task = (Runnable)tasks.remove();
+            if (task==null && idle.size() < minThreads) idle.append(this);
+            else if (task==null)                        die = true;
+        }
+        public void run() {
+            try {
+                while (!die) {
+                    try {
+                        synchronized(this) { while (task==null) wait(); }
+                        task.run();
+                    } catch (Exception e) { Log.error(this, e); }
+                    recycle();
+                }
+            } finally {
+                numThreads--;
+            }
+        }
+    }
+
+}
+