From: adam Date: Fri, 18 Mar 2005 09:11:41 +0000 (+0000) Subject: added ThreadPool class X-Git-Url: http://git.megacz.com/?p=org.ibex.util.git;a=commitdiff_plain;h=47cc5f30ae0a5aa928c2f6044599cce96e0a000a added ThreadPool class darcs-hash:20050318091141-5007d-03d815051e82d3328d2b93a1da5fe7fa0678850f.gz --- diff --git a/src/org/ibex/util/ThreadPool.java b/src/org/ibex/util/ThreadPool.java new file mode 100644 index 0000000..30e490f --- /dev/null +++ b/src/org/ibex/util/ThreadPool.java @@ -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--; + } + } + } + +} +