You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by bl...@apache.org on 2001/03/01 21:11:04 UTC

cvs commit: jakarta-avalon/src/java/org/apache/avalon/util/thread ThreadPool.java

bloritsch    01/03/01 12:11:03

  Modified:    src/java/org/apache/avalon/util/datasource
                        JdbcConnectionPool.java
               src/java/org/apache/avalon/util/pool AbstractPool.java
                        DefaultObjectFactory.java DefaultPool.java
                        ObjectFactory.java ThreadSafePool.java
               src/java/org/apache/avalon/util/thread ThreadPool.java
  Added:       src/java/org/apache/avalon/util/pool Resizable.java
                        SingleThreadedPool.java
  Log:
  Beefed up the AbstractPool and ThreadsafePool.
  
  Both should be robust for multithreaded environments.
  
  Revision  Changes    Path
  1.2       +10 -6     jakarta-avalon/src/java/org/apache/avalon/util/datasource/JdbcConnectionPool.java
  
  Index: JdbcConnectionPool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/util/datasource/JdbcConnectionPool.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JdbcConnectionPool.java	2001/02/24 03:59:38	1.1
  +++ JdbcConnectionPool.java	2001/03/01 20:10:47	1.2
  @@ -24,7 +24,7 @@
    * thread to manage the number of SQL Connections.
    *
    * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
  - * @version CVS $Revision: 1.1 $ $Date: 2001/02/24 03:59:38 $
  + * @version CVS $Revision: 1.2 $ $Date: 2001/03/01 20:10:47 $
    */
   public class JdbcConnectionPool
       extends AbstractLoggable
  @@ -145,9 +145,13 @@
           }
           else
           {
  -            synchronized( m_active )
  +            synchronized( m_ready )
               {
                   obj = (Poolable)m_ready.remove( 0 );
  +            }
  +
  +            synchronized( m_active )
  +            {
                   m_active.add( obj );
               }
           }
  @@ -180,7 +184,7 @@
                   if( m_ready.size() < m_min )
                   {
                       getLogger().debug( "There are not enough Connections for pool: " + m_dburl );
  -                    
  +
                       while( ( m_ready.size() < m_min ) && ( m_currentCount < m_max ) )
                       {
                           m_ready.add( createJdbcConnection() );
  @@ -190,17 +194,17 @@
                   {
                       getLogger().debug( "Trimming excess fat from pool: " + m_dburl );
   
  -                    while( m_ready.size() > m_min ) 
  +                    while( m_ready.size() > m_min )
                       {
                           recycle( (Recyclable)m_ready.remove( 0 ) );
  -                    } 
  +                    }
                   }
               }
   
               try
               {
                   Thread.sleep( 1 * 60 * 1000 );
  -            } 
  +            }
               catch( final InterruptedException ie )
               {
                   getLogger().warn( "Caught an InterruptedException", ie );
  
  
  
  1.2       +101 -106  jakarta-avalon/src/java/org/apache/avalon/util/pool/AbstractPool.java
  
  Index: AbstractPool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/util/pool/AbstractPool.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractPool.java	2001/02/24 03:59:41	1.1
  +++ AbstractPool.java	2001/03/01 20:10:51	1.2
  @@ -7,153 +7,148 @@
    */
   package org.apache.avalon.util.pool;
   
  +import java.util.ArrayList;
  +import java.util.List;
  +
  +import org.apache.avalon.AbstractLoggable;
  +import org.apache.avalon.Initializable;
   import org.apache.avalon.Poolable;
   import org.apache.avalon.Recyclable;
  -import org.apache.avalon.Initializable;
   
   /**
    * This is an <code>Pool</code> that caches Poolable objects for reuse.
    *
    * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
  - * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
  - * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
    */
  -public class AbstractPool
  -    implements Pool, Initializable
  -{
  -    protected int                     m_count;
  -    protected Poolable[]              m_pool;
  -    protected ObjectFactory           m_factory;
  -    protected PoolController          m_controller;
  -    protected int                     m_maximum;
  -    protected int                     m_initial;
  +public class AbstractPool extends AbstractLoggable implements Pool {
   
  +    protected final ObjectFactory  m_factory;
  +    protected final PoolController m_controller;
  +    protected final int            m_min;
  +    protected int                  m_max;
  +    protected int                  m_currentCount  = 0;
  +    protected List                 m_active        = new ArrayList();
  +    protected List                 m_ready         = new ArrayList();
  +
  +    /**
  +     * Create an AbstractPool.  The pool requires a factory, and can
  +     * optionally have a controller.
  +     */
       public AbstractPool( final ObjectFactory factory,
                            final PoolController controller,
  -                         final int initial,
  -                         final int maximum )
  +                         final int min,
  +                         final int max ) throws Exception
       {
  -        m_count = 0;
           m_factory = factory;
           m_controller = controller;
  -        m_maximum = maximum;
  -        m_initial = initial;
  -    }
  -
  -    public void init() 
  -        throws Exception
  -    {
  -        grow( m_maximum );
  -        fill( m_initial );
  -    }
  +        int t_max = max;
  +        int t_min = min;
   
  -    /**
  -     * Retrieve an object from pool.
  -     *
  -     * @return an object from Pool
  -     */
  -    public Poolable get() throws Exception
  -    {
  -        if( null == m_pool && null != m_controller )
  +        if( min < 0 )
           {
  -            final int increase = m_controller.grow();
  -            if( increase > 0 ) grow( increase );
  -        }
  +            if (getLogger() != null)
  +                getLogger().warn( "Minumum number of connections specified is " +
  +                                  "less than 0, using 0" );
   
  -        if( 0 == m_count )
  +            t_min = 0;
  +        }
  +        else
           {
  -            return m_factory.newInstance();
  +            t_min = min;
           }
  -
  -        m_count--;
  -
  -        final Poolable poolable = m_pool[ m_count ];
  -        m_pool[ m_count ] = null;
  -        return poolable;
  -    }
   
  -    /**
  -     * Place an object in pool.
  -     *
  -     * @param poolable the object to be placed in pool
  -     */
  -    public void put( final Poolable poolable )
  -    {
  -        if( poolable instanceof Recyclable )
  +        if( ( max < min ) || ( max < 1 ) )
           {
  -            ((Recyclable)poolable).recycle();
  +            if (getLogger() != null)
  +                getLogger().warn( "Maximum number of connections specified must be at " +
  +                                  "least 1 and must be greater than the minumum number " +
  +                                  "of connections" );
  +            t_max = ( min > 1 ) ? min : 1;
           }
  -
  -        if(  m_pool.length == (m_count + 1) && null != m_controller )
  +        else
           {
  -            final int decrease = m_controller.shrink();
  -            if( decrease > 0 ) shrink( decrease );
  +            t_max = max;
           }
   
  -        if ( m_pool.length > m_count + 1 )
  -        {
  -            m_pool[ m_count++ ] = poolable;
  +        m_max = t_max;
  +        m_min = t_min;
  +
  +        if (! (this instanceof Initializable)) {
  +            init();
           }
       }
   
  -    /**
  -     * Return the total number of slots in Pool
  -     *
  -     * @return the total number of slots
  -     */
  -    public final int getCapacity()
  +    protected void init() throws Exception
       {
  -        return m_pool.length;
  +        for( int i = 0; i < m_min; i++ )
  +        {
  +            m_ready.add( m_factory.newInstance() );
  +            m_currentCount++;
  +        }
       }
   
  -    /**
  -     * Get the number of used slots in Pool
  -     *
  -     * @return the number of used slots
  -     */
  -    public final int getSize()
  +    public synchronized Poolable get()
  +        throws Exception
       {
  -        return m_count;
  -    }
  +        Poolable obj = null;
   
  -    /**
  -     * This fills the pool to the size specified in parameter.
  -     */
  -    public final void fill( final int fillSize ) throws Exception
  -    {
  -        final int size = Math.min( m_pool.length, fillSize );
  +        if( 0 == m_ready.size() )
  +        {
  +            if( m_currentCount < m_max )
  +            {
  +                int amount = (m_controller == null) ? 1 : m_controller.grow();
  +                obj = m_factory.newInstance();
  +                m_active.add( obj );
  +                m_currentCount++;
  +                amount--;
   
  -        for( int i = m_count; i < size; i++ )
  +                while ((amount > 0) && (m_currentCount < m_max)) {
  +                    m_ready.add( m_factory.newInstance() );
  +                    m_currentCount++;
  +                    amount--;
  +                    notify();
  +                }
  +            }
  +            else
  +            {
  +                if (this instanceof Resizable) {
  +                    int amount = (m_controller == null) ? 1 : m_controller.grow();
  +                    ((Resizable) this).grow(amount);
  +                    return get();
  +                } else {
  +                    throw new Exception( m_factory.getCreatedClass().getName() + ": not available" );
  +                }
  +            }
  +        }
  +        else
           {
  -            m_pool[i] = m_factory.newInstance();
  +            obj = (Poolable)m_ready.remove( 0 );
  +            m_active.add( obj );
           }
  +
  +        if (getLogger() != null)
  +            getLogger().debug( m_factory.getCreatedClass().getName() + ": requested from the pool." );
   
  -        m_count = size;
  +        return obj;
       }
   
  -    /**
  -     * This fills the pool by the size specified in parameter.
  -     */
  -    public final void grow( final int increase )
  +    public synchronized void put( final Poolable obj )
       {
  -        if( null == m_pool )
  +        if (! m_active.remove( obj ))
           {
  -            m_pool = new Poolable[ increase ];
  -            return;
  +            try {
  +                m_factory.decommission( obj );
  +            } catch (Exception e) {
  +                if (getLogger() != null)
  +                    getLogger().warn( m_factory.getCreatedClass().getName() + ": error decommissioning object.", e );
  +            }
           }
  -
  -        final Poolable[] poolables = new Poolable[ increase + m_pool.length ];
  -        System.arraycopy( m_pool, 0, poolables, 0, m_pool.length );
  -        m_pool = poolables;
  -    }
  +        else
  +        {
  +            m_ready.add( obj );
  +        }
   
  -    /**
  -     * This shrinks the pool by parameter size.
  -     */
  -    public final void shrink( final int decrease )
  -    {
  -        final Poolable[] poolables = new Poolable[ m_pool.length - decrease ];
  -        System.arraycopy( m_pool, 0, poolables, 0, poolables.length );
  -        m_pool = poolables;
  +        if (getLogger() != null)
  +            getLogger().debug( m_factory.getCreatedClass().getName() + ": returned to the pool." );
       }
  -}
  +}
  \ No newline at end of file
  
  
  
  1.2       +10 -5     jakarta-avalon/src/java/org/apache/avalon/util/pool/DefaultObjectFactory.java
  
  Index: DefaultObjectFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/util/pool/DefaultObjectFactory.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DefaultObjectFactory.java	2001/02/24 03:59:41	1.1
  +++ DefaultObjectFactory.java	2001/03/01 20:10:51	1.2
  @@ -32,8 +32,8 @@
           m_constructor = constructor;
       }
   
  -    public DefaultObjectFactory( final Class clazz, 
  -                                 final Class[] arguementClasses, 
  +    public DefaultObjectFactory( final Class clazz,
  +                                 final Class[] arguementClasses,
                                    final Object[] arguements )
           throws NoSuchMethodException
       {
  @@ -56,11 +56,16 @@
           try
           {
               return (Poolable)m_constructor.newInstance( m_arguements );
  -        } 
  -        catch( final Exception e ) 
  +        }
  +        catch( final Exception e )
           {
  -            throw new Error( "Failed to instantiate the class " + 
  +            throw new Error( "Failed to instantiate the class " +
                                m_constructor.getDeclaringClass().getName() + " due to " + e );
           }
  +    }
  +
  +    public void decommission(Poolable object)
  +    {
  +       object = null;
       }
   }
  
  
  
  1.2       +6 -6      jakarta-avalon/src/java/org/apache/avalon/util/pool/DefaultPool.java
  
  Index: DefaultPool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/util/pool/DefaultPool.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DefaultPool.java	2001/02/24 03:59:41	1.1
  +++ DefaultPool.java	2001/03/01 20:10:52	1.2
  @@ -18,30 +18,30 @@
    * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
    */
   public class DefaultPool
  -    extends AbstractPool
  +    extends SingleThreadedPool
   {
       public final static int           DEFAULT_POOL_SIZE           = 8;
   
  -    public DefaultPool( final ObjectFactory factory, 
  -                        final PoolController controller ) 
  +    public DefaultPool( final ObjectFactory factory,
  +                        final PoolController controller )
           throws Exception
       {
           super( factory, controller, DEFAULT_POOL_SIZE, DEFAULT_POOL_SIZE );
       }
   
  -    public DefaultPool( final ObjectFactory factory ) 
  +    public DefaultPool( final ObjectFactory factory )
           throws Exception
       {
           this( factory, null );
       }
   
  -    public DefaultPool( final Class clazz, final int initial, final int maximum ) 
  +    public DefaultPool( final Class clazz, final int initial, final int maximum )
           throws NoSuchMethodException, Exception
       {
           super( new DefaultObjectFactory( clazz ), null, initial, maximum );
       }
   
  -    public DefaultPool( final Class clazz, final int initial ) 
  +    public DefaultPool( final Class clazz, final int initial )
           throws NoSuchMethodException, Exception
       {
           this( clazz, initial, initial );
  
  
  
  1.2       +2 -1      jakarta-avalon/src/java/org/apache/avalon/util/pool/ObjectFactory.java
  
  Index: ObjectFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/util/pool/ObjectFactory.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ObjectFactory.java	2001/02/24 03:59:41	1.1
  +++ ObjectFactory.java	2001/03/01 20:10:53	1.2
  @@ -17,9 +17,10 @@
    * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
    * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
    */
  -public interface ObjectFactory 
  +public interface ObjectFactory
       extends Component
   {
       Poolable newInstance() throws Exception;
       Class getCreatedClass();
  +    void decommission(Poolable object) throws Exception;
   }
  
  
  
  1.2       +25 -63    jakarta-avalon/src/java/org/apache/avalon/util/pool/ThreadSafePool.java
  
  Index: ThreadSafePool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/util/pool/ThreadSafePool.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ThreadSafePool.java	2001/02/24 03:59:41	1.1
  +++ ThreadSafePool.java	2001/03/01 20:10:53	1.2
  @@ -7,6 +7,7 @@
    */
   package org.apache.avalon.util.pool;
   
  +import org.apache.avalon.Initializable;
   import org.apache.avalon.Poolable;
   import org.apache.avalon.Recyclable;
   import org.apache.avalon.ThreadSafe;
  @@ -20,102 +21,69 @@
    */
   public class ThreadSafePool
       extends AbstractPool
  -    implements ThreadSafe
  +    implements ThreadSafe, Initializable
   {
       public final static int           DEFAULT_POOL_SIZE           = 8;
   
  -    protected boolean                 m_blocking                  = false;
  -
       public ThreadSafePool( final ObjectFactory factory, final PoolController controller )
  -        throws Exception 
  +        throws Exception
       {
           super( factory, controller, DEFAULT_POOL_SIZE, DEFAULT_POOL_SIZE );
       }
   
       public ThreadSafePool( final ObjectFactory factory )
  -        throws Exception 
  +        throws Exception
       {
           this( factory, null );
       }
   
  -    public ThreadSafePool( final ObjectFactory factory, 
  -                           final int initial, 
  +    public ThreadSafePool( final ObjectFactory factory,
  +                           final int initial,
                              final int maximum  )
  -        throws Exception 
  +        throws Exception
       {
           super( factory, null, initial, maximum );
       }
   
       public ThreadSafePool( final ObjectFactory factory, final int initial )
  -        throws Exception 
  +        throws Exception
       {
           this( factory, initial, initial );
       }
   
  -    public ThreadSafePool( final Class clazz, final int initial, final int maximum ) 
  +    public ThreadSafePool( final Class clazz, final int initial, final int maximum )
           throws NoSuchMethodException, Exception
       {
           this( new DefaultObjectFactory( clazz ), initial, maximum );
       }
   
  -    public ThreadSafePool( final Class clazz, final int initial ) 
  +    public ThreadSafePool( final Class clazz, final int initial )
           throws NoSuchMethodException, Exception
       {
           this( clazz, initial, initial );
       }
  -
  -    public final boolean isBlocking() 
  -    {
  -        return m_blocking;
  -    }
   
  -    /**
  -     * Set whether this pool is blocking. 
  -     * 
  -     * If this pool is blocking and empties the Pool then the thread will block until
  -     * an object is placed back in the pool. This has to be used with care as an errant
  -     * thread who never does a put will force blocked clients to wait forever.
  -     *
  -     * @param blocking a boolean indicating if it is blocking or not
  -     */
  -    public final void setBlocking( final boolean blocking ) 
  -    {
  -        m_blocking = blocking;
  +    public void init() {
  +        try {
  +            super.init();
  +        } catch (Exception e) {
  +            getLogger().debug("Caught init exception", e);
  +        }
       }
  -
       /**
        * Retrieve an object from pool.
        *
        * @return an object from Pool
        */
  -    public final Poolable get() throws Exception 
  +    public final synchronized Poolable get() throws Exception
       {
  -        //Require this or else the wait later will cause 
  -        final Poolable[] pool = m_pool;
  -
  -        synchronized( pool )
  +        while ( this.m_ready.size() == 0 )
           {
  -            if( 0 == m_count )
  -            {
  -                if( !m_blocking ) 
  -                {
  -                    return m_factory.newInstance();
  -                }
  -                else
  -                {
  -                    while( 0 == m_count )
  -                    {
  -                        try { pool.wait(); }
  -                        catch( final InterruptedException ie ) { }
  -                    }
  -                }
  -            }
  -
  -            m_count--;
  -            final Poolable poolable = m_pool[ m_count ];
  -            m_pool[ m_count ] = null;
  -            return poolable;
  +            try { wait(); }
  +            catch( final InterruptedException ie ) { }
           }
  +
  +        return super.get();
       }
   
       /**
  @@ -123,16 +91,10 @@
        *
        * @param poolable the object to be placed in pool
        */
  -    public final void put( final Poolable poolable ) 
  +    public final synchronized void put( final Poolable poolable )
       {
  -        final Poolable[] pool = m_pool;
  +        super.put( poolable );
   
  -        synchronized( pool )
  -        {
  -            super.put( poolable );
  -
  -            //if someone was waiting on the old pool then we have to notify them
  -            pool.notifyAll();
  -        }
  +        notify();
       }
   }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/avalon/util/pool/Resizable.java
  
  Index: Resizable.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.util.pool;
  
  /**
   * This is the interface for Pools that are not a fixed size.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   */
  public interface Resizable {
  
      void grow(int amount);
      void shrink(int amount);
  }
  
  
  1.1                  jakarta-avalon/src/java/org/apache/avalon/util/pool/SingleThreadedPool.java
  
  Index: SingleThreadedPool.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.util.pool;
  
  import org.apache.avalon.Poolable;
  import org.apache.avalon.Recyclable;
  import org.apache.avalon.Initializable;
  import org.apache.avalon.SingleThreaded;
  
  /**
   * This is an <code>Pool</code> that caches Poolable objects for reuse.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class SingleThreadedPool
      implements Pool, SingleThreaded, Resizable
  {
      protected int                     m_count;
      protected Poolable[]              m_pool;
      protected ObjectFactory           m_factory;
      protected PoolController          m_controller;
      protected int                     m_maximum;
      protected int                     m_initial;
  
      public SingleThreadedPool( final ObjectFactory factory,
                                 final PoolController controller,
                                 final int initial,
                                 final int maximum ) throws Exception
      {
          m_count = 0;
          m_factory = factory;
          m_controller = controller;
          m_maximum = maximum;
          m_initial = initial;
  
          if (! (this instanceof Initializable)) {
              init();
          }
      }
  
      public void init()
          throws Exception
      {
          grow( m_maximum );
          fill( m_initial );
      }
  
      /**
       * Retrieve an object from pool.
       *
       * @return an object from Pool
       */
      public Poolable get() throws Exception
      {
          if( null == m_pool && null != m_controller )
          {
              final int increase = m_controller.grow();
              if( increase > 0 ) grow( increase );
          }
  
          if( 0 == m_count )
          {
              return m_factory.newInstance();
          }
  
          m_count--;
  
          final Poolable poolable = m_pool[ m_count ];
          m_pool[ m_count ] = null;
          return poolable;
      }
  
      /**
       * Place an object in pool.
       *
       * @param poolable the object to be placed in pool
       */
      public void put( final Poolable poolable )
      {
          if( poolable instanceof Recyclable )
          {
              ((Recyclable)poolable).recycle();
          }
  
          if(  m_pool.length == (m_count + 1) && null != m_controller )
          {
              final int decrease = m_controller.shrink();
              if( decrease > 0 ) shrink( decrease );
          }
  
          if ( m_pool.length > m_count + 1 )
          {
              m_pool[ m_count++ ] = poolable;
          }
      }
  
      /**
       * Return the total number of slots in Pool
       *
       * @return the total number of slots
       */
      public final int getCapacity()
      {
          return m_pool.length;
      }
  
      /**
       * Get the number of used slots in Pool
       *
       * @return the number of used slots
       */
      public final int getSize()
      {
          return m_count;
      }
  
      /**
       * This fills the pool to the size specified in parameter.
       */
      public final void fill( final int fillSize ) throws Exception
      {
          final int size = Math.min( m_pool.length, fillSize );
  
          for( int i = m_count; i < size; i++ )
          {
              m_pool[i] = m_factory.newInstance();
          }
  
          m_count = size;
      }
  
      /**
       * This fills the pool by the size specified in parameter.
       */
      public final void grow( final int increase )
      {
          if( null == m_pool )
          {
              m_pool = new Poolable[ increase ];
              return;
          }
  
          final Poolable[] poolables = new Poolable[ increase + m_pool.length ];
          System.arraycopy( m_pool, 0, poolables, 0, m_pool.length );
          m_pool = poolables;
      }
  
      /**
       * This shrinks the pool by parameter size.
       */
      public final void shrink( final int decrease )
      {
          final Poolable[] poolables = new Poolable[ m_pool.length - decrease ];
          System.arraycopy( m_pool, 0, poolables, 0, poolables.length );
          m_pool = poolables;
      }
  }
  
  
  
  1.2       +15 -10    jakarta-avalon/src/java/org/apache/avalon/util/thread/ThreadPool.java
  
  Index: ThreadPool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/util/thread/ThreadPool.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ThreadPool.java	2001/02/24 03:59:43	1.1
  +++ ThreadPool.java	2001/03/01 20:11:01	1.2
  @@ -21,7 +21,7 @@
    * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
    * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
    */
  -public class ThreadPool 
  +public class ThreadPool
       extends ThreadGroup
       implements ObjectFactory, Loggable
   {
  @@ -36,12 +36,11 @@
       }
   
       public ThreadPool( final String name, final int capacity )
  -        throws Exception 
  +        throws Exception
       {
           super( name );
           m_pool = new ThreadSafePool( this, 0 );
           m_pool.init();
  -        m_pool.grow( capacity );
       }
   
       public void setLogger( final Logger logger )
  @@ -51,38 +50,44 @@
   
       public Poolable newInstance()
       {
  -        final WorkerThread worker = 
  +        final WorkerThread worker =
               new WorkerThread( this, m_pool, getName() + " Worker #" + m_level++ );
           worker.setLogger( m_logger );
           worker.start();
           return worker;
       }
   
  +    public void decommission(Poolable object) {
  +        if (object instanceof WorkerThread) {
  +            ((WorkerThread) object).dispose();
  +        }
  +    }
  +
       public Class getCreatedClass()
       {
           return WorkerThread.class;
       }
  -        
  -    public void execute( final Runnable work ) 
  +
  +    public void execute( final Runnable work )
           throws Exception
       {
           execute( work, Thread.NORM_PRIORITY );
       }
   
  -    public void execute( final Runnable work, final int priority ) 
  +    public void execute( final Runnable work, final int priority )
           throws Exception
       {
           final WorkerThread worker = getWorker( priority );
           worker.execute( work );
       }
  -    
  -    public void executeAndWait( final Runnable work ) 
  +
  +    public void executeAndWait( final Runnable work )
           throws Exception
       {
           executeAndWait( work, Thread.NORM_PRIORITY );
       }
   
  -    public void executeAndWait( final Runnable work, final int priority ) 
  +    public void executeAndWait( final Runnable work, final int priority )
           throws Exception
       {
           final WorkerThread worker = getWorker( priority );