Costin Manolache wrote:

You're probably right that addThread() doesn't need to be public - but
I don't think it hurts too much either.
It does when you're trying to refactor a class. It forces you to ask whether the interface really is used, or can you rearrange like you want to. Usually I grep the sources to determine that, but when you're using reflection/introspection (e.g., JMX), then there's no telling. You have to take an educated guess and hope that you don't break things.

It also prevents the byte code compiler from doing complete, inlined optimization when a member is non-private.

Also: MonitorRunnable, now that it has a start() method (for JMX, I presume) has no restriction on running more than one thread. This undercuts the meaning of "interval", and makes stop() poorly defined.

IMO MonitorRunnable, the session expiration thread ( one per ctx )
and the reloading thread ( one per ctx again )
What classes are you referring to specifically? StandardManager & WebappLoader?

should all go away and
be replaced by a single mechanism. Maybe the JMX timer ?
I'd hate to think what would happen if someone stopped the timer service. Also, using the event-driven approach to trigger maintenance activities in foreground threads would be quirky coding, and may not even be appropriate in classes that don't always have executing code.

So I'd opt for java.util.Timer. It requires J2SE 1.3+...is that a problem? Here's what it looks like:

* Replace MonitorRunnable with java.util.Timer.
* The Timer thread is always daemonized; I couldn't understand why
MonitorRunnable would conditionally do so based on ThreadPool.
* Unlike the start/stop() MonitorRunnable i/f--which I assumed was
for activating the new wait() interval--the Timer can never be
stopped w/o shutting down the ThreadPool.



Index: ThreadPool.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/threads/ThreadPool.java,v
retrieving revision 1.6
diff -u -r1.6 ThreadPool.java
--- ThreadPool.java     24 Dec 2002 17:02:54 -0000      1.6
+++ ThreadPool.java     28 Dec 2002 08:29:12 -0000
@@ -90,6 +90,34 @@
      */
     protected MonitorRunnable monitor;
 
+    /**
+     * Timer for scheduling maintenance runs.
+     * A lock on this variable should be considered to apply to
+     * {@link #maintenanceInterval} as well.
+     */
+    private Timer maintenanceTimer = null;
+
+    /** Milliseconds between maintenance runs */
+
+    private long maintenanceInterval = WORK_WAIT_TIMEOUT;
+
+    /**
+     * Maintenance task to remove idle <code>ControlRunnable</code>s
+     */
+    private class MaintenanceTask extends TimerTask
+    {
+       public void run()
+       {
+           try {
+               checkSpareControllers();
+           }
+           catch (Throwable t) {
+               log.error( "maintenance task exception (continuing task anyway):" + t 
+);
+               // don't cancel(), keep trying
+           }
+       }
+    }
+
 
     /*
      * Max number of threads that you can open in the pool.
@@ -158,12 +186,39 @@
 
         openThreads(minSpareThreads);
         monitor = new MonitorRunnable(this);
+       startMaintenanceTimer();
+    }
+
+
+    /**
+     * Sets the time interval between maintenance runs.
+     * Silently enforces a minimum (currently 10 milliseconds).
+     * Also re-creates the maintenance thread.
+     */
+    public void setMaintenanceInterval( long milliseconds )
+    {
+       if (milliseconds < 10)  milliseconds = 10;
+
+       synchronized (maintenanceTimer) {
+           maintenanceInterval = milliseconds;
+           startMaintenanceTimer();
+       }
     }
 
-    public MonitorRunnable getMonitor() {
-        return monitor;
+
+    /** (Re)start the maintenance timer. */
+
+    private void startMaintenanceTimer()
+    {
+       synchronized (maintenanceTimer) {
+           if (maintenanceTimer != null)  maintenanceTimer.cancel();
+           maintenanceTimer = new Timer( true );
+           maintenanceTimer.schedule( new MaintenanceTask(), 0,
+                                      maintenanceInterval );
+       }
     }
 
+
     public void setMaxThreads(int maxThreads) {
         this.maxThreads = maxThreads;
     }
@@ -319,8 +374,14 @@
     public synchronized void shutdown() {
         if(!stopThePool) {
             stopThePool = true;
-            monitor.terminate();
-            monitor = null;
+
+           synchronized (maintenanceTimer) {
+               if (maintenanceTimer != null) {
+                   maintenanceTimer.cancel();
+                   maintenanceTimer = null;
+               }
+           }
+
             for(int i = 0 ; i < (currentThreadCount - currentThreadsBusy - 1) ; i++) {
                 try {
                     pool[i].terminate();
@@ -443,66 +504,6 @@
        //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( "MonitorRunnable" );
-            t.start();
-        }
-
-        public void setInterval(int i ) {
-            this.interval=i;
-        }
-
-        public void run() {
-            while(true) {
-                try {
-                    // Sleep for a while.
-                    synchronized(this) {
-                        this.wait(WORK_WAIT_TIMEOUT);
-                    }
-
-                    // 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 )

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to