Mega Code Archive

 
Categories / Java / Threads
 

Simple pool of Threads

/*  * Copyright (c) 1998 - 2005 Versant Corporation  * All rights reserved. This program and the accompanying materials  * are made available under the terms of the Eclipse Public License v1.0  * which accompanies this distribution, and is available at  * http://www.eclipse.org/legal/epl-v10.html  *  * Contributors:  * Versant Corporation - initial API and implementation  */ import java.util.LinkedList; import java.util.Iterator; import java.util.HashSet; /**  * Simple pool of Threads.  */ public class ThreadPool {     private String name;     private HashSet active = new HashSet();     private LinkedList idle = new LinkedList();     private int idleCount;     private int maxActive = 10;     private int maxIdle = 3;     private int lastThreadId;     private boolean closed;     public ThreadPool(String name) {         this.name = name;     }     public int getMaxActive() {         return maxActive;     }     public void setMaxActive(int maxActive) {         this.maxActive = maxActive;     }     public int getMaxIdle() {         return maxIdle;     }     public void setMaxIdle(int maxIdle) {         this.maxIdle = maxIdle;     }     public synchronized int getActiveCount() {         return active.size();     }     public synchronized int getIdleCount() {         return idleCount;     }     /**      * Close the pool, stopping all threads. This does not wait for the      * threads to actually stop before returning. This is a NOP if the      * pool has already been closed.      */     public synchronized void close() {         if (closed) {             return;         }         closed = true;         for (Iterator i = idle.iterator(); i.hasNext(); ) {             Worker w = (Worker)i.next();             w.terminate();         }         idle = null;         idleCount = 0;         for (Iterator i = active.iterator(); i.hasNext(); ) {             Worker w = (Worker)i.next();             w.terminate();         }         active = null;     }     /**      * Executed runnable using a Thread from the pool. This will block for      * timeoutMs and forever if this is 0. Returns true if the task is      * being executed (i.e. a Thread was available) or false if not (i.e.      * pool full).      */     public synchronized boolean execute(Runnable runnable, int timeoutMs) {         if (closed) {             throw new IllegalStateException("Pool has been closed");         }         Worker t;         if (idleCount == 0) {             for (; isFull(); ) {                 try {                     wait(timeoutMs);                     if (isFull()) {                         return false;                     }                 } catch (InterruptedException e) {                     // ignore                 }             }             t = new Worker();         } else {             t = (Worker)idle.removeFirst();             --idleCount;         }         active.add(t);         t.execute(runnable);         return true;     }     protected boolean isFull() {         return active.size() >= maxActive;     }     private synchronized void finishedWork(Worker t) {         if (!closed) {             active.remove(t);             if (idleCount >= maxIdle) {                 t.terminate();             } else {                 idle.addLast(t);                 ++idleCount;             }         }     }     private class Worker extends Thread {         private boolean stopFlag;         private Runnable runnable;         public Worker() {             super(name + " " + ++lastThreadId);             setDaemon(true);         }         /**          * Executed runnable.          */         public void execute(Runnable runnable) {             this.runnable = runnable;             if (!isAlive()) {                 start();             } else {                 synchronized (this) {                     notify();                 }             }         }         /**          * Stop this thread as soon as possible.          */         public void terminate() {             stopFlag = true;             interrupt();         }         public void run() {             for (; !stopFlag; ) {                 try {                     runnable.run();                 } catch (Throwable e) {                     if (e instanceof ThreadDeath) {                         throw (ThreadDeath)e;                     }                 }                 runnable = null;                 finishedWork(this);                 if (stopFlag) break;                 synchronized (this) {                     try {                         wait();                     } catch (InterruptedException e) {                         // ignore                     }                 }             }         }     } }