User: osh
Date: 00/11/30 13:27:38
Modified: src/main/org/jboss/web ThreadPool.java
Log:
Client hang fix
Revision Changes Path
1.3 +134 -101 jboss/src/main/org/jboss/web/ThreadPool.java
Index: ThreadPool.java
===================================================================
RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/web/ThreadPool.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ThreadPool.java 2000/08/18 03:21:13 1.2
+++ ThreadPool.java 2000/11/30 21:27:38 1.3
@@ -11,124 +11,157 @@
import org.jboss.logging.Logger;
/**
- * <description>
+ * A simple thread pool.
*
- * @see <related>
- * @author Rickard �berg ([EMAIL PROTECTED])
- * @version $Revision: 1.2 $
+ * @author Rickard �berg ([EMAIL PROTECTED])
+ * @version $Revision: 1.3 $
*/
public class ThreadPool
{
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
- Stack pool = new Stack();
-
- int maxSize = 10;
-
+
+ /**
+ * Stack of idle threads cached for future use.
+ */
+ private Stack pool = new Stack();
+
+ /**
+ * Maximum number of idle threads cached in this pool.
+ */
+ private int maxSize = 10;
+
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
+
+ /**
+ * Create a new pool.
+ */
public ThreadPool()
{
}
-
+
// Public --------------------------------------------------------
-
- public synchronized void clear()
- {
- for (int i = 0; i < pool.size(); i++)
- {
- Worker w = (Worker)pool.get(i);
- w.stop();
- }
- }
-
- public void setMaximumSize(int size)
- {
- maxSize = size;
- }
-
- public synchronized void run(Runnable work)
- {
- if (pool.size() == 0)
- {
- new Worker().run(work);
- } else
- {
- Worker w = (Worker)pool.pop();
- w.run(work);
- }
- }
-
-
- // Package protected ---------------------------------------------
- synchronized void returnWorker(Worker w)
+
+ /**
+ * Set the maximum number of idle threads cached in this pool.
+ */
+ public void setMaximumSize(int size)
+ {
+ maxSize = size;
+ }
+
+ /**
+ * Do some work.
+ * This will either create a new thread to do the work, or
+ * use an existing idle cached thread.
+ */
+ public synchronized void run(Runnable work)
+ {
+ if (pool.size() == 0) {
+ new Worker(work);
+ } else {
+ Worker w = (Worker)pool.pop();
+ w.run(work);
+ }
+ }
+
+ // Private -------------------------------------------------------
+
+ /**
+ * Return an idle worker thread to the pool of cached idle threads.
+ * This is called from the worker thread itself.
+ */
+ private synchronized void returnWorker(Worker w)
{
- if (pool.size() < maxSize)
- pool.push(w);
- else
- w.die();
+ if (pool.size() < maxSize)
+ pool.push(w);
+ else
+ w.die();
}
-
+
// Inner classes -------------------------------------------------
- class Worker
- extends Thread
- {
- boolean running = true;
-
- Runnable runner;
-
- Worker()
- {
- start();
- }
-
- public synchronized void die()
- {
- running = false;
- }
-
- public synchronized void run(Runnable runner)
- {
- this.runner = runner;
- notifyAll();
- }
-
- public void run()
- {
- while (running)
- {
- // Wait for work to become available
- synchronized (this)
- {
- try
- {
- wait(5000);
- } catch (InterruptedException e)
- {
- // Ignore
- }
- }
-
- // If work is available then execute it
- if (runner != null)
- {
- try
- {
- runner.run();
- } catch (Exception e)
- {
- //DEBUG Logger.exception(e);
- }
- // Clear work
- runner = null;
- }
+
+ class Worker extends Thread
+ {
+ /**
+ * Flags that this worker may continue to work.
+ */
+ boolean running = true;
+
+ /**
+ * Work to do, of <code>null</code> if no work to do.
+ */
+ Runnable work;
+
+ /**
+ * Create a new Worker to do some work.
+ */
+ Worker(Runnable work)
+ {
+ this.work = work;
+ setDaemon(true);
+ start();
+ }
+
+ /**
+ * Tell this worker to die.
+ */
+ public synchronized void die()
+ {
+ running = false;
+ notify();
+ }
+
+ /**
+ * Give this Worker some work to do.
+ *
+ * @throws IllegalStateException If this worker already
+ * has work to do.
+ */
+ public synchronized void run(Runnable work)
+ {
+ if (this.work != null)
+ throw new IllegalStateException("Worker already has work to do.");
+ this.work = work;
+ notify();
+ }
+
+ /**
+ * The worker loop.
+ */
+ public void run()
+ {
+ while (running) {
+ // If work is available then execute it
+ if (work != null) {
+ try {
+ work.run();
+ } catch (Exception e) {
+ //DEBUG Logger.exception(e);
+ }
+ // Clear work
+ work = null;
+ }
- // Return to pool
- returnWorker(this);
- }
- }
- }
+ // Return to pool of cached idle threads
+ returnWorker(this);
+
+ // Wait for more work to become available
+ synchronized (this) {
+ while (running && work == null) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+ }
+ }
+ }
+
+ }
}