FileDocCategorySizeDatePackage
SoftObjectPool.javaAPI DocGlassfish v2 API11750Fri May 04 22:32:18 BST 2007com.sun.enterprise.util.pool

SoftObjectPool

public class SoftObjectPool extends com.sun.enterprise.util.pool.AbstractPool implements com.sun.enterprise.util.scheduler.PeriodicallyServicable

$Source: /cvs/glassfish/appserv-commons/src/java/com/sun/enterprise/util/pool/SoftObjectPool.java,v $
author
$Author: tcfujii $
version
$Revision: 1.5 $ $Date: 2007/05/05 05:32:17 $

Fields Summary
static Logger
_logger
protected com.sun.enterprise.util.collection.DList
list
protected int
minSize
protected int
initialSize
protected int
maxLimit
protected long
maxIdleTime
protected int
maxStrongRefs
protected Boolean
isBounded
Constructors Summary
public SoftObjectPool(ObjectFactory factory, int minSize, int initialSize, long maxIdleTime, int maxStrongRefs)
Create an Unbounded pool.

param
The ObjectFactory to create objects
param
The minimum number of objects to be held in the pool (initial size)
param
The initial size of the pool. If this is less than the minSize parameter then this is ignored.
param
The maximum idle time after which the object may be removed from the pool.
param
The pool limit (maximum number of objects in the pool).

	
	                                                                     	 
           
    			    
        super();
        super.factory = factory;
        this.minSize = minSize;
        this.initialSize = initialSize;
        this.maxIdleTime = maxIdleTime;
        this.maxStrongRefs = maxStrongRefs;
        
        setMaxLimit(-1);
        
        initPool();
    
public SoftObjectPool(ObjectFactory factory, int minSize, int initialSize, int maxLimit, long maxIdleTime, int maxStrongRefs)
Create a Bounded pool.

param
The ObjectFactory to create objects
param
The minimum number of objects to be held in the pool (initial size)
param
The pool limit (maximum number of objects in the pool).
param
The maximum idle time after which the object may be removed from the pool.
param
The initial size of the pool. If this is less than the minSize parameter then this is ignored.

        super();
        super.factory = factory;
        this.minSize = minSize;
        this.maxIdleTime = maxIdleTime;
        this.initialSize = initialSize;
        this.maxStrongRefs = maxStrongRefs;
        
        setMaxLimit(maxLimit);
        
        initPool();
    
Methods Summary
protected booleancanCreate()
Since this method would be called only if the pool is empty

        return (isBounded == null) ? true : (createdCount < maxLimit);
    
protected java.lang.Objectcheckin(java.lang.Object object)
Notification when an object is put back into the pool (checkin).

param
The object to be returned back to the pool.
return
Any non null value can be returned to signal that the object was indeed added to the pool. This class always adds the object to the pool (at the end of the list), it returns non-null value. Subclasses can override this behaviour.

		int size = list.size();
		long now = _clock.getTime();

		if (size < maxStrongRefs) {
			list.addAsLastNode(new TimeStampedSoftDListNode(object, now, object));
		} else {
			list.addAsLastNode(new TimeStampedSoftDListNode(new SoftReference(object), now, null));
		}

    	return this;
    
protected java.lang.Objectcheckout(java.lang.Object param)
Notification when an object is given out from the pool (checout).

return
The object that has to be returned to the application. A null value must be returned if no object can be returned to the application. Since this class always returns the last node from the list, it returns non-null value. Subclasses can override this behaviour.

		return obtainObject(param);
    
public voidepilog()

    
public booleangetExecuteIfMissed()
Determine to execute the service method of this object even if it has missed the right schedule.

    	return true;
    
public booleangetExecutionTolerance(long missedByMillis)
Determine to execute the service method of this object when the schedule is delayed by 'missedByMillis' milli seconds.

    	return true;
    
public longgetFrequency()
Get the frequency (time interval) at which service() method will be invoked.

return
time in milli seconds.

    	return this.maxIdleTime;
    
public intgetMaxLimit()

    	return this.maxLimit;
    
private voidinitPool()

        list = new DList();
        
        super.collection = list;
        super.preload((minSize < initialSize) ? initialSize : minSize);
        
        scheduler.addTimeRepeatableTask(this, (int) maxIdleTime);
    
private java.lang.ObjectobtainObject(java.lang.Object param)

		SoftReference ref;
		Object object = null;
		int notifyCount = 0;
		
		for (int size = list.size(); size > 0; size--) {
			TimeStampedSoftDListNode tsNode = (TimeStampedSoftDListNode) list.getDListNodeAt(0);
			list.delink(tsNode);
			
			if (tsNode.isSoftRef == null) {
				ref = (SoftReference) tsNode.object;
				if ((object = ref.get()) != null) {
					break;
				} else {
					notifyCount++;
				}
			} else {
				object = tsNode.object;
				break;
			}
		}
			
		if (object == null) {
			try {
				object = factory.create(param);
				afterCreate(object);
			} catch (PoolException poolEx) {
				
			}
		}
		
		super.createdCount -= notifyCount;
		
		if (notifyCount == 1) {
			super.collection.notify();
		} else if (notifyCount > 1) {
			super.collection.notifyAll();
		}
		
		return object;
    
public voidprolog()

    
public voidservice()

   		int killedCount = 0;
   		
    	long now = _clock.getTime();
    	long allowed = now - maxIdleTime;
   		
   		TimeStampedSoftDListNode tsNode = null;
   		FastStack stack = new FastStack();
   		
   		synchronized (super.collection) {

   			Object done = null;
   			while (done == null) {
   				tsNode = (TimeStampedSoftDListNode) list.getFirstDListNode();
	   			
   				if (tsNode == null) {	//Empty list
   					done = new Object();
   				} else if (tsNode.timeStamp <= allowed) {
    				//Need to destroy the contained object
    				list.delink(tsNode);
    				stack.push(tsNode.object);
    				killedCount++;
    			} else {
    				//This node is not old enough
   					done = new Object();
    			}
    		}	//End of for loop
    		
    		super.createdCount -= killedCount;
    		
    		int deficit = list.size() - minSize;
    		super.preload(0 - deficit);
    		
    		if (killedCount == 0) {
    		} else if (killedCount == 1) {
    			collection.notify();
    		} else {
    			collection.notifyAll();
    		}
    		
    	} // end of synchronized
    	
    	
    	//Now destroy all collected objects
    	while (! stack.isEmpty()) {
    		Object object = stack.pop();
			beforeDestroy(object);
   			factory.destroy(object);
    	}
    	
//Bug 4677074    	System.out.println("Leaving service after killing " + killedCount + " (idle) objects. Now size: " + list.size());
//Bug 4677074 begin
		_logger.log(Level.FINE,"Leaving service after killing " + killedCount + " (idle) objects. Now size: " + list.size());
//Bug 4677074 end
    
public voidsetMaxLimit(int limit)

        if ((limit <= 0) || (limit >= Integer.MAX_VALUE-1)) {
        	this.isBounded = null;
        } else {
        	this.isBounded = Boolean.valueOf(true);
        	this.maxLimit = limit;
        }
    
public java.lang.StringtoString()
Print an identification for the object.

    	return "";