Return-Path: Delivered-To: apmail-tomcat-dev-archive@www.apache.org Received: (qmail 72433 invoked from network); 4 Jan 2006 04:11:26 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 4 Jan 2006 04:11:26 -0000 Received: (qmail 96613 invoked by uid 500); 4 Jan 2006 04:11:21 -0000 Delivered-To: apmail-tomcat-dev-archive@tomcat.apache.org Received: (qmail 96311 invoked by uid 500); 4 Jan 2006 04:11:20 -0000 Mailing-List: contact dev-help@tomcat.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Tomcat Developers List" Delivered-To: mailing list dev@tomcat.apache.org Received: (qmail 96300 invoked by uid 500); 4 Jan 2006 04:11:20 -0000 Delivered-To: apmail-jakarta-tomcat-dev@jakarta.apache.org Received: (qmail 96297 invoked by uid 99); 4 Jan 2006 04:11:20 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 03 Jan 2006 20:11:20 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Tue, 03 Jan 2006 20:11:19 -0800 Received: (qmail 72317 invoked by uid 65534); 4 Jan 2006 04:10:59 -0000 Message-ID: <20060104041059.72314.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r365816 - /tomcat/sandbox/java/org/apache/tomcat/util/threads/ThreadPool.java Date: Wed, 04 Jan 2006 04:10:58 -0000 To: tomcat-dev@jakarta.apache.org From: costin@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: costin Date: Tue Jan 3 20:10:57 2006 New Revision: 365816 URL: http://svn.apache.org/viewcvs?rev=365816&view=rev Log: Since this is sandbox, let's see if we can get rid of the monitor thread, and instead do the same checks on each worker thread, before and after a task is performed. Also expose the controller, to make it a bit more flexible and avoid wrappings Modified: tomcat/sandbox/java/org/apache/tomcat/util/threads/ThreadPool.java Modified: tomcat/sandbox/java/org/apache/tomcat/util/threads/ThreadPool.java URL: http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/util/threads/ThreadPool.java?rev=365816&r1=365815&r2=365816&view=diff ============================================================================== --- tomcat/sandbox/java/org/apache/tomcat/util/threads/ThreadPool.java (original) +++ tomcat/sandbox/java/org/apache/tomcat/util/threads/ThreadPool.java Tue Jan 3 20:10:57 2006 @@ -45,7 +45,6 @@ public static final int MAX_THREADS_MIN = 10; public static final int MAX_SPARE_THREADS = 50; public static final int MIN_SPARE_THREADS = 4; - public static final int WORK_WAIT_TIMEOUT = 60*1000; /* * Where the threads are held. @@ -53,12 +52,6 @@ protected ControlRunnable[] pool = null; /* - * A monitor thread that monitors the pool for idel threads. - */ - protected MonitorRunnable monitor; - - - /* * Max number of threads that you can open in the pool. */ protected int maxThreads; @@ -146,13 +139,6 @@ pool = new ControlRunnable[maxThreads]; openThreads(minSpareThreads); - if (maxSpareThreads < maxThreads) { - monitor = new MonitorRunnable(this); - } - } - - public MonitorRunnable getMonitor() { - return monitor; } /** @@ -286,7 +272,7 @@ } public void run(Runnable r) { - ControlRunnable c = findControlRunnable(); + ControlRunnable c = findControlRunnable(true); c.runIt(r); } @@ -301,16 +287,25 @@ * Executes a given Runnable on a thread in the pool, block if needed. */ public void runIt(ThreadPoolRunnable r) { - ControlRunnable c = findControlRunnable(); + ControlRunnable c = findControlRunnable(true); c.runIt(r); } public void runIt(ThreadPoolRunnable r, Object param) { - ControlRunnable c = findControlRunnable(); + ControlRunnable c = findControlRunnable(true); c.runIt(r, param); } - private ControlRunnable findControlRunnable() { + /** Find a worker thread and remove it from the pool. + * + * If the pool is stopping, will generate a runtime exception to + * block the processing. + * + * + * @param waitForThread if true, will wait for a thread to become available. + * @return + */ + public ControlRunnable findControlRunnable(boolean waitForThread) { ControlRunnable c=null; if ( stopThePool ) { @@ -329,6 +324,9 @@ openThreads(toOpen); } else { logFull(log, currentThreadCount, maxThreads); + if( ! waitForThread ) { + return null; + } // Wait for a thread to become idel. try { this.wait(); @@ -385,10 +383,6 @@ public synchronized void shutdown() { if(!stopThePool) { stopThePool = true; - if (monitor != null) { - monitor.terminate(); - monitor = null; - } for(int i = 0; i < currentThreadCount - currentThreadsBusy; i++) { try { pool[i].terminate(); @@ -406,6 +400,16 @@ } } + boolean checkSpare() { + if( stopThePool ) { + return true; // die, the pool is stopped + } + if( (currentThreadCount - currentThreadsBusy) > maxSpareThreads ) { + return true; + } + return false; + } + /** * Called by the monitor thread to harvest idle threads. */ @@ -525,71 +529,9 @@ //loghelper.flush(); } - /** - * Periodically execute an action - cleanup in this case - */ - public static class MonitorRunnable implements Runnable { - ThreadPool p; - Thread t; - int interval=WORK_WAIT_TIMEOUT; - boolean shouldTerminate; - - MonitorRunnable(ThreadPool p) { - this.p=p; - this.start(); - } - - public void start() { - shouldTerminate = false; - t = new Thread(this); - t.setDaemon(p.getDaemon() ); - t.setName(p.getName() + "-Monitor"); - t.start(); - } - - public void setInterval(int i ) { - this.interval=i; - } - - public void run() { - while(true) { - try { - - // Sleep for a while. - synchronized(this) { - this.wait(interval); - } - - // Check if should terminate. - // termination happens when the pool is shutting down. - if(shouldTerminate) { - break; - } - - // Harvest idle threads. - p.checkSpareControllers(); - - } catch(Throwable t) { - ThreadPool.log.error("Unexpected exception", t); - } - } - } - - public void stop() { - this.terminate(); - } - - /** Stop the monitor - */ - public synchronized void terminate() { - shouldTerminate = true; - this.notify(); - } - } - /** - * A Thread object that executes various actions ( ThreadPoolRunnable ) - * under control of ThreadPool + * The Runnable object that executes various actions ( ThreadPoolRunnable ) + * under control of ThreadPool. This is associated with a ThreadWithAttribute. */ public static class ControlRunnable implements Runnable { /** @@ -690,6 +632,17 @@ ThreadPool.log.debug("No toRun ???"); } } + + // After a task is done, we can check if there are + // threads that need to go. In particular - the + // current thread could terminate. + if( p.checkSpare() ) { + _shouldRun = false; // to not return + _shouldTerminate = true; + p.notifyThreadEnd(this); + break; + } + } catch (Throwable t) { ThreadPool.log.error(sm.getString ("threadpool.thread_error", t, toRun.toString())); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org For additional commands, e-mail: dev-help@tomcat.apache.org