org.apache.avalon.excalibur.pool
Class InstrumentedResourceLimitingPool

java.lang.Object
  extended by org.apache.avalon.framework.logger.AbstractLogEnabled
      extended by org.apache.avalon.excalibur.pool.InstrumentedResourceLimitingPool
All Implemented Interfaces:
org.apache.avalon.excalibur.pool.Pool, org.apache.avalon.framework.activity.Disposable, org.apache.avalon.framework.logger.LogEnabled, org.apache.avalon.framework.thread.ThreadSafe, org.apache.excalibur.instrument.Instrumentable
Direct Known Subclasses:
TraceableResourceLimitingPool

public class InstrumentedResourceLimitingPool
extends org.apache.avalon.framework.logger.AbstractLogEnabled
implements org.apache.avalon.excalibur.pool.Pool, org.apache.avalon.framework.logger.LogEnabled, org.apache.avalon.framework.activity.Disposable, org.apache.avalon.framework.thread.ThreadSafe, org.apache.excalibur.instrument.Instrumentable

General Pool implementation which supports; weak and strong pool size limits, optional blocking gets when poolables are not available, and automatic pool trimming of unused poolables.

Whenever get() is called, the pool tests to see whether it is time to trim old poolables from the pool. If any old poolables exist then they are removed at this time. This means that old poolables will not be removed if get() is never called. Applications can optionally call trim() to force old objects to be trimmed. See the trim() method for details of how trimming works.

Since:
4.1
Version:
CVS $Revision: 1.1 $ $Date: 2004/03/29 16:50:37 $
Author:
Avalon Development Team

Field Summary
static java.lang.String DEFAULT_INSTRUMENTABLE_NAME
           
static java.lang.String INSTRUMENT_BLOCKS_NAME
           
static java.lang.String INSTRUMENT_CREATES_NAME
           
static java.lang.String INSTRUMENT_DECOMMISSIONS_NAME
           
static java.lang.String INSTRUMENT_GETS_NAME
           
static java.lang.String INSTRUMENT_PUTS_NAME
           
static java.lang.String INSTRUMENT_READY_SIZE_NAME
           
static java.lang.String INSTRUMENT_SIZE_NAME
           
private  boolean m_blocking
          Whether or not the pool should cause threads requesting a Poolable to block when m_maxStrict is true, the pool size is equal to m_max and there are no Poolable instances available.
private  org.apache.excalibur.instrument.CounterInstrument m_blocksInstrument
          Instrument used to profile the number of blocks.
private  long m_blockTimeout
          The maximum amount of time in milliseconds that the pool will block.
private  org.apache.excalibur.instrument.CounterInstrument m_createsInstrument
          Instrument used to profile the number of created poolables.
private  org.apache.excalibur.instrument.CounterInstrument m_decommissionsInstrument
          Instrument used to profile the number of decommissioned poolables.
private  boolean m_disposed
          Keeps track of whether or not the Pool has been disposed.
private  org.apache.avalon.excalibur.pool.ObjectFactory m_factory
          The Object Factory used to generate new Poolable instances for the pool.
private  org.apache.excalibur.instrument.CounterInstrument m_getsInstrument
          Instrument used to profile the number of gets.
private  java.lang.String m_instrumentableName
          Instrumentable Name assigned to this Instrumentable
private  long m_lastTrim
          The last time that the pool was trimmed.
private  int m_max
          The maximum size of the pool.
private  boolean m_maxStrict
          Whether or not the pool allows for the creation of objects beyond the maximum pool size.
private  java.util.LinkedList m_oldReady
          List of the Poolable instance which are available for use but have been idle for a while.
private  int m_oldReadySize
          Store the size of the old ready list to optimize operations which require this value.
private  org.apache.excalibur.instrument.CounterInstrument m_putsInstrument
          Instrument used to profile the number of puts.
private  java.util.LinkedList m_ready
          List of the Poolable instances which are available for use.
private  int m_readySize
          Store the size of the ready list to optimize operations which require this value.
private  org.apache.excalibur.instrument.ValueInstrument m_readySizeInstrument
          Instrument used to profile the number of available poolables.
protected  java.lang.Object m_semaphore
          Object used to synchronize access to the get and put methods
private  int m_size
          Total number of Poolable instances in the pool
private  org.apache.excalibur.instrument.ValueInstrument m_sizeInstrument
          Instrument used to profile the size of the pool.
private  long m_trimInterval
          The minimum interval with which old unused poolables will be removed from the pool.
 
Fields inherited from interface org.apache.excalibur.instrument.Instrumentable
EMPTY_INSTRUMENT_ARRAY, EMPTY_INSTRUMENTABLE_ARRAY
 
Constructor Summary
InstrumentedResourceLimitingPool(org.apache.avalon.excalibur.pool.ObjectFactory factory, int max, boolean maxStrict, boolean blocking, long blockTimeout, long trimInterval)
          Creates a new InstrumentedResourceLimitingPool
 
Method Summary
 void dispose()
          The dispose operation is called at the end of a components lifecycle.
 org.apache.avalon.excalibur.pool.Poolable get()
          Gets a Poolable from the pool.
 org.apache.excalibur.instrument.Instrumentable[] getChildInstrumentables()
          Any Object which implements Instrumentable can also make use of other Instrumentable child objects.
 java.lang.String getInstrumentableName()
          Gets the name of the Instrumentable.
 org.apache.excalibur.instrument.Instrument[] getInstruments()
          Obtain a reference to all the Instruments that the Instrumentable object wishes to expose.
 int getReadySize()
          Returns the number of available Poolables waiting in the pool.
private  int getReadySizeSync()
          Returns the number of available Poolables waiting in the pool.
 int getSize()
          Returns the total number of Poolables created by the pool.
protected  org.apache.avalon.excalibur.pool.Poolable newPoolable()
          Create a new poolable instance by by calling the newInstance method on the pool's ObjectFactory.
protected  void permanentlyRemovePoolable(org.apache.avalon.excalibur.pool.Poolable poolable)
          Permanently removes a poolable from the pool's active list and destroys it so that it will not ever be reused.
 void put(org.apache.avalon.excalibur.pool.Poolable poolable)
          Returns a poolable to the pool and notifies any thread blocking.
protected  void removePoolable(org.apache.avalon.excalibur.pool.Poolable poolable)
          Called when an object is being removed permanently from the pool.
 void setInstrumentableName(java.lang.String name)
          Sets the name for the Instrumentable.
 int trim()
          Forces the pool to trim, remove, old Poolables from the pool.
private  int trimInner()
          See trim() for details.
 
Methods inherited from class org.apache.avalon.framework.logger.AbstractLogEnabled
enableLogging, getLogger, setupLogger, setupLogger, setupLogger
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface org.apache.avalon.framework.logger.LogEnabled
enableLogging
 

Field Detail

DEFAULT_INSTRUMENTABLE_NAME

public static final java.lang.String DEFAULT_INSTRUMENTABLE_NAME
See Also:
Constant Field Values

INSTRUMENT_SIZE_NAME

public static final java.lang.String INSTRUMENT_SIZE_NAME
See Also:
Constant Field Values

INSTRUMENT_READY_SIZE_NAME

public static final java.lang.String INSTRUMENT_READY_SIZE_NAME
See Also:
Constant Field Values

INSTRUMENT_GETS_NAME

public static final java.lang.String INSTRUMENT_GETS_NAME
See Also:
Constant Field Values

INSTRUMENT_PUTS_NAME

public static final java.lang.String INSTRUMENT_PUTS_NAME
See Also:
Constant Field Values

INSTRUMENT_BLOCKS_NAME

public static final java.lang.String INSTRUMENT_BLOCKS_NAME
See Also:
Constant Field Values

INSTRUMENT_CREATES_NAME

public static final java.lang.String INSTRUMENT_CREATES_NAME
See Also:
Constant Field Values

INSTRUMENT_DECOMMISSIONS_NAME

public static final java.lang.String INSTRUMENT_DECOMMISSIONS_NAME
See Also:
Constant Field Values

m_semaphore

protected final java.lang.Object m_semaphore
Object used to synchronize access to the get and put methods


m_disposed

private boolean m_disposed
Keeps track of whether or not the Pool has been disposed.


m_factory

private final org.apache.avalon.excalibur.pool.ObjectFactory m_factory
The Object Factory used to generate new Poolable instances for the pool.


m_max

private final int m_max
The maximum size of the pool.


m_maxStrict

private final boolean m_maxStrict
Whether or not the pool allows for the creation of objects beyond the maximum pool size.


m_blocking

private final boolean m_blocking
Whether or not the pool should cause threads requesting a Poolable to block when m_maxStrict is true, the pool size is equal to m_max and there are no Poolable instances available.


m_blockTimeout

private final long m_blockTimeout
The maximum amount of time in milliseconds that the pool will block. If 0, blocking will wait indeffinately.


m_trimInterval

private final long m_trimInterval
The minimum interval with which old unused poolables will be removed from the pool.


m_lastTrim

private long m_lastTrim
The last time that the pool was trimmed.


m_ready

private java.util.LinkedList m_ready
List of the Poolable instances which are available for use.


m_readySize

private int m_readySize
Store the size of the ready list to optimize operations which require this value.


m_oldReady

private java.util.LinkedList m_oldReady
List of the Poolable instance which are available for use but have been idle for a while.


m_oldReadySize

private int m_oldReadySize
Store the size of the old ready list to optimize operations which require this value.


m_size

private int m_size
Total number of Poolable instances in the pool


m_instrumentableName

private java.lang.String m_instrumentableName
Instrumentable Name assigned to this Instrumentable


m_sizeInstrument

private org.apache.excalibur.instrument.ValueInstrument m_sizeInstrument
Instrument used to profile the size of the pool.


m_readySizeInstrument

private org.apache.excalibur.instrument.ValueInstrument m_readySizeInstrument
Instrument used to profile the number of available poolables.


m_getsInstrument

private org.apache.excalibur.instrument.CounterInstrument m_getsInstrument
Instrument used to profile the number of gets.


m_putsInstrument

private org.apache.excalibur.instrument.CounterInstrument m_putsInstrument
Instrument used to profile the number of puts.


m_blocksInstrument

private org.apache.excalibur.instrument.CounterInstrument m_blocksInstrument
Instrument used to profile the number of blocks.


m_createsInstrument

private org.apache.excalibur.instrument.CounterInstrument m_createsInstrument
Instrument used to profile the number of created poolables.


m_decommissionsInstrument

private org.apache.excalibur.instrument.CounterInstrument m_decommissionsInstrument
Instrument used to profile the number of decommissioned poolables.

Constructor Detail

InstrumentedResourceLimitingPool

public InstrumentedResourceLimitingPool(org.apache.avalon.excalibur.pool.ObjectFactory factory,
                                        int max,
                                        boolean maxStrict,
                                        boolean blocking,
                                        long blockTimeout,
                                        long trimInterval)
Creates a new InstrumentedResourceLimitingPool

Parameters:
factory - The ObjectFactory which will be used to create new Poolables as needed by the pool.
max - Maximum number of Poolables which can be stored in the pool, 0 implies no limit.
maxStrict - true if the pool should never allow more than max Poolable to be created. Will cause an exception to be thrown if more than max Poolables are requested and blocking is false.
blocking - true if the pool should cause a thread calling get() to block when Poolables are not currently available in the pool.
blockTimeout - The maximum amount of time, in milliseconds, that a call to get() will block before an exception is thrown. A value of 0 implies an indefinate wait.
trimInterval - The minimum interval with which old unused poolables will be removed from the pool. A value of 0 will cause the pool to never trim poolables.
Method Detail

get

public org.apache.avalon.excalibur.pool.Poolable get()
                                              throws java.lang.Exception
Gets a Poolable from the pool. If there is room in the pool, a new Poolable will be created. Depending on the parameters to the constructor, the method may block or throw an exception if a Poolable is not available on the pool.

Specified by:
get in interface org.apache.avalon.excalibur.pool.Pool
Returns:
Always returns a Poolable. Contract requires that put must always be called with the Poolable returned.
Throws:
java.lang.Exception - An exception may be thrown as described above or if there is an exception thrown by the ObjectFactory's newInstance() method.

put

public void put(org.apache.avalon.excalibur.pool.Poolable poolable)
Returns a poolable to the pool and notifies any thread blocking.

Specified by:
put in interface org.apache.avalon.excalibur.pool.Pool
Parameters:
poolable - Poolable to return to the pool.

dispose

public void dispose()
The dispose operation is called at the end of a components lifecycle. This method will be called after Startable.stop() method (if implemented by component). Components use this method to release and destroy any resources that the Component owns.

Specified by:
dispose in interface org.apache.avalon.framework.activity.Disposable

setInstrumentableName

public void setInstrumentableName(java.lang.String name)
Sets the name for the Instrumentable. The Instrumentable Name is used to uniquely identify the Instrumentable during the configuration of the InstrumentManager and to gain access to an InstrumentableDescriptor through the InstrumentManager. The value should be a string which does not contain spaces or periods.

This value may be set by a parent Instrumentable, or by the InstrumentManager using the value of the 'instrumentable' attribute in the configuration of the component.

Specified by:
setInstrumentableName in interface org.apache.excalibur.instrument.Instrumentable
Parameters:
name - The name used to identify a Instrumentable.

getInstrumentableName

public java.lang.String getInstrumentableName()
Gets the name of the Instrumentable.

Specified by:
getInstrumentableName in interface org.apache.excalibur.instrument.Instrumentable
Returns:
The name used to identify a Instrumentable.

getInstruments

public org.apache.excalibur.instrument.Instrument[] getInstruments()
Obtain a reference to all the Instruments that the Instrumentable object wishes to expose. All sampling is done directly through the Instruments as opposed to the Instrumentable interface.

Specified by:
getInstruments in interface org.apache.excalibur.instrument.Instrumentable
Returns:
An array of the Instruments available for profiling. Should never be null. If there are no Instruments, then EMPTY_INSTRUMENT_ARRAY can be returned. This should never be the case though unless there are child Instrumentables with Instruments.

getChildInstrumentables

public org.apache.excalibur.instrument.Instrumentable[] getChildInstrumentables()
Any Object which implements Instrumentable can also make use of other Instrumentable child objects. This method is used to tell the InstrumentManager about them.

Specified by:
getChildInstrumentables in interface org.apache.excalibur.instrument.Instrumentable
Returns:
An array of child Instrumentables. This method should never return null. If there are no child Instrumentables, then EMPTY_INSTRUMENTABLE_ARRAY can be returned.

permanentlyRemovePoolable

protected void permanentlyRemovePoolable(org.apache.avalon.excalibur.pool.Poolable poolable)
Permanently removes a poolable from the pool's active list and destroys it so that it will not ever be reused.

This method is only called by threads that have m_semaphore locked.


getSize

public int getSize()
Returns the total number of Poolables created by the pool. Includes active and ready.

Returns:
The total size.

getReadySizeSync

private int getReadySizeSync()
Returns the number of available Poolables waiting in the pool. Only called when synchronized.

Returns:
The ready size.

getReadySize

public int getReadySize()
Returns the number of available Poolables waiting in the pool.

Returns:
The ready size.

newPoolable

protected org.apache.avalon.excalibur.pool.Poolable newPoolable()
                                                         throws java.lang.Exception
Create a new poolable instance by by calling the newInstance method on the pool's ObjectFactory.

This is the method to override when you need to enforce creational policies.

This method is only called by threads that have m_semaphore locked.

Throws:
java.lang.Exception

removePoolable

protected void removePoolable(org.apache.avalon.excalibur.pool.Poolable poolable)
Called when an object is being removed permanently from the pool. This is the method to override when you need to enforce destructional policies.

This method is only called by threads that have m_semaphore locked.

Parameters:
poolable - Poolable to be completely removed from the pool.

trim

public int trim()
Forces the pool to trim, remove, old Poolables from the pool. If the Pool was created with a non-zero value for trimInterval, then this method will be called at that interval when get() is called. If get() is not called for long periods of time then if may be necessary to call this method manually.

Trimming is done by maintaining two lists of objects. The first is a ready list of new poolables. The second is a list of old poolables. Each time trim() is called, the contents of the old list are removed from the pool. Then the contents of the new list is moved into the old list.

Each time get() is called on the pool, the new list is checked first, then the old list is checked, finally a new poolable may be created if both lists are empty. Then whenever put() is called, the poolables are always returned to the new list. In this way, the need for maining time stamps for each poolable can be avoided while at the same time avoiding unnecessary removal and creation on poolables.

This works out to a poolable having a maximum idle time of two calls to trim() or twice the value of trimInterval.

NOTE - The trimming feature does not harm performance because pools with high load will not have old poolables to be trimmed, and the benefits to system resources from not keeping around unused poolables makes up for any hit.

Returns:
the number of Poolables that were trimmed.

trimInner

private int trimInner()
See trim() for details. This method is only called by threads that have m_semaphore locked.