📄 objectpool.java
字号:
/**
* Sets the minimum idle time to release an unused object from the pool. If
* the object is not in use and has not been used for this amount of time,
* it will be released from the pool. If timestamps are enabled, the client
* may update the last used time. Otherwise, the last used time is only
* updated when an object is acquired or released. The default value is
* 30 minutes.
* @see #setIdleTimeoutEnabled
* @param millis The idle time, in milliseconds.
* @throws java.lang.IllegalStateException
* Occurs when you try to set the idle timeout after the pool
* has been initialized.
*/
public void setIdleTimeout(long millis) {
if (initialized)
throw new IllegalStateException(INITIALIZED);
idleTimeoutMillis = millis;
if (log.isDebugEnabled())
log.debug("setIdleTimeout(" + millis + ")");
}
/**
* Gets the minimum idle time to release an unused object from the pool.
* @see #setIdleTimeout
*/
public long getIdleTimeout() {
return idleTimeoutMillis;
}
/**
* Sets the minimum idle time to make an object eligible for garbage
* collection. If the object is in use and has not been used for this
* amount of time, it may be returned to the pool. If timestamps are
* enabled, the client may update the last used time (this is generally
* recommended if garbage collection is enabled). Otherwise, the last used
* time is only updated when an object is acquired or released. The default
* value is 20 minutes.
* @see #setGCEnabled
* @param millis The idle time, in milliseconds.
* @throws java.lang.IllegalStateException
* Occurs when you try to set the garbage collection idle time after the
* pool has been initialized.
*/
public void setGCMinIdleTime(long millis) {
if (initialized)
throw new IllegalStateException(INITIALIZED);
gcMinIdleMillis = millis;
if (log.isDebugEnabled())
log.debug("setGCMinIdleTime(" + millis + ")");
}
/**
* Gets the minimum idle time to make an object eligible for garbage
* collection.
* @see #setGCMinIdleTime
*/
public long getGCMinIdleTime() {
return gcMinIdleMillis;
}
/**
* Sets the length of time between garbage collection and idle timeout runs.
* This is inexact - if there are many pools with garbage collection and/or
* the idle timeout enabled, there will not be a thread for each one, and
* several nearby actions may be combined. Likewise if the collection
* process is lengthy for certain types of pooled objects (not recommended),
* other actions may be delayed. This is to prevend an unnecessary
* proliferation of threads. Note that this parameter controls
* both garbage collection and the idle timeout - and they will be performed
* together if both are enabled. The deafult value is 2 minutes.
* @throws java.lang.IllegalStateException
* Occurs when you try to set the garbage collection interval after the
* pool has been initialized.
*/
public void setGCInterval(long millis) {
if (initialized)
throw new IllegalStateException(INITIALIZED);
gcIntervalMillis = millis;
if (log.isDebugEnabled())
log.debug("setGCInterval(" + gcIntervalMillis + ")");
}
/**
* Gets the length of time between garbage collection and idle timeout runs.
* @see #setGCInterval
*/
public long getGCInterval() {
return gcIntervalMillis;
}
/**
* Sets whether a request for an object will block if the pool size is
* maxed out and no objects are available. If set to block, the request
* will not return until an object is available. Otherwise, the request
* will return null immediately (and may be retried). If multiple
* requests block, there is no guarantee which will return first. The
* default is to block.
* @throws java.lang.IllegalStateException
* Occurs when you try to set the blocking parameter after the
* pool has been initialized.
*/
public void setBlocking(boolean blocking) {
if (initialized)
throw new IllegalStateException(INITIALIZED);
this.blocking = blocking;
}
/**
* Gets whether a request for an object will block if the pool size is
* maxed out and no objects are available.
* @see #setBlocking
*/
public boolean isBlocking() {
return blocking;
}
/** sets how long to wait for a free object when blocking, -1 indicating
* forever.
*/
public void setBlockingTimeout(int blockingTimeout) {
this.blockingTimeout = blockingTimeout;
}
/** get how long this pool will wait for a free object while blocking */
public int getBlockingTimeout() {
return this.blockingTimeout;
}
/**
* Sets whether object clients can update the last used time. If not, the
* last used time will only be updated when the object is given to a client
* and returned to the pool. This time is important if the idle timeout or
* garbage collection is enabled (particularly the latter). The default
* is false.
* @throws java.lang.IllegalStateException
* Occurs when you try to set the timestamp parameter after the
* pool has been initialized.
*/
public void setTimestampUsed(boolean timestamp) {
if (initialized)
throw new IllegalStateException(INITIALIZED);
trackLastUsed = timestamp;
if (log.isDebugEnabled())
log.debug("setTimestampUsed(" + timestamp + ")");
}
/**
* Gets whether object clients can update the last used time.
*/
public boolean isTimestampUsed() {
return trackLastUsed;
}
/**
* Sets the response for object errors. If this flag is set and an error
* event occurs, the object is removed from the pool entirely. Otherwise,
* the object is returned to the pool of available objects. For example, a
* SQL error may not indicate a bad database connection (flag not set),
* while a TCP/IP error probably indicates a bad network connection (flag
* set). If this flag is not set, you can still manually invalidate
* objects using markObjectAsInvalid.
* @see #markObjectAsInvalid
* @see #objectError
*/
public void setInvalidateOnError(boolean invalidate) {
if (initialized)
throw new IllegalStateException(INITIALIZED);
invalidateOnError = invalidate;
}
/**
* Gets whether objects are removed from the pool in case of errors.
*/
public boolean isInvalidateOnError() {
return invalidateOnError;
}
/**
* Prepares the pool for use. This must be called exactly once before
* getObject is even called. The pool name and object factory must be set
* before this call will succeed.
* @throws java.lang.IllegalStateException
* Occurs when you try to initialize the pool without setting the object
* factory or name, or you initialize the pool more than once.
*/
public void initialize() {
if (factory == null || poolName == null)
throw new IllegalStateException("Factory and Name must be set before pool initialization!");
if (initialized)
throw new IllegalStateException("Cannot initialize more than once!");
initialized = true;
permits = new FIFOSemaphore(maxSize);
factory.poolStarted(this);
lastGC = System.currentTimeMillis();
//fill pool to min size
fillToMin();
/*
int max = maxSize <= 0 ? minSize : Math.min(minSize, maxSize);
Collection cs = new LinkedList();
for(int i=0; i<max; i++)
{
cs.add(getObject(null));
}
while (Iterator i = cs.iterator(); i.hasNext();)
{
releaseObject(i.next());
} // end of while ()
*/
collector.addPool(this);
}
/**
* Shuts down the pool. All outstanding objects are closed and all objects
* are released from the pool. No getObject or releaseObject calls will
* succeed after this method is called - and they will probably fail during
* this method call.
*/
public void shutDown() {
collector.removePool(this);
factory.poolClosing(this);
// close all objects
synchronized (objects) {
for (Iterator it = objects.values().iterator(); it.hasNext();) {
ObjectRecord rec = (ObjectRecord) it.next();
if (null != rec) {
if (rec.isInUse())
factory.returnObject(rec.getClientObject());
factory.deleteObject(rec.getObject());
rec.close();
}
}
objects.clear();
deadObjects.clear();
}//end of synch
factory = null;
poolName = null;
initialized = false;
}
/**
* Gets an object from the pool. If all the objects in the pool are in use,
* creates a new object, adds it to the pool, and returns it. If all
* objects are in use and the pool is at maximum size, will block or
* return null.
* @see #setBlocking
*/
public Object getObject() {
return getObject(null);
}
/**
* Gets an object that fits the specified parameters from the pool.
* If all the objects in the pool are in use or don't fit, creates
* a new object, adds it to the pool, and returns it. If all
* objects are in use or don't fit and the pool is at maximum size,
* will block or return null.
* @see #setBlocking
*/
public Object getObject(Object parameters) {
if (objects == null)
throw new IllegalStateException("Tried to use pool before it was Initialized or after it was ShutDown!");
Object result = factory.isUniqueRequest();
if (result != null) // If this is identical to a previous request,
return result; // return the same result. This is the 2.4 total hack to
//share local connections within a managed tx.
try {
if (permits.attempt(blockingTimeout)) {
ObjectRecord rec = null;
synchronized (objects) {
for (Iterator it = objects.values().iterator(); it.hasNext();) {
rec = (ObjectRecord) it.next();
if (null != rec && !rec.isInUse() && factory.checkValidObject(rec.getObject(), parameters)) {
log.info("Handing out from pool object: " + rec.getObject());
try {
rec.setInUse(true);
} catch (ConcurrentModificationException e) {
log.info("Conflict trying to set rec. in use flag:" + rec.getObject());
// That's OK, just go on and try another object
continue;//shouldn't happen now.
}
break;
}
rec = null;//not found
}
}//synch on objects
if (rec == null) {
rec = createNewObject(parameters);
} // end of if ()
if (rec == null) {
throw new RuntimeException("Pool is broken, did not find or create an object");
} // end of if ()
Object ob = rec.getObject();
result = factory.prepareObject(ob);
if (result != ob) rec.setClientObject(result);
if (result instanceof PooledObject)
((PooledObject) result).addPoolEventListener(this);
log.debug("Pool " + this + " gave out object: " + result);
return result;
}//end of permits
else {
//we timed out
throw new RuntimeException("No ManagedConnections Available!");
} // end of else
}//try
catch (RuntimeException e) {
throw e;
} // end of catch
catch (InterruptedException ie) {
log.info("Interrupted while requesting permit!", new Exception("stacktrace"));
throw new RuntimeException("Interrupted while requesting permit!");
} // end of try-catch
catch (Exception e) {
log.info("problem getting connection from pool", e);
throw new RuntimeException("problem getting connection from pool " + e.getMessage());
} // end of catch
}
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -