⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 poolmanager.java

📁 java开源的企业总线.xmlBlaster
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------------Name:      PoolManager.javaProject:   xmlBlaster.orgCopyright: xmlBlaster.org, see xmlBlaster-LICENSE file------------------------------------------------------------------------------*/package org.xmlBlaster.util.pool;import org.xmlBlaster.util.XmlBlasterException;import org.xmlBlaster.util.Timeout;import org.xmlBlaster.util.def.ErrorCode;import java.util.Hashtable;import java.util.Vector;import java.util.Enumeration;/** * A little framework to handle a pool of limited resources. * <p /> * You can use this pool as a base class handling of your limited resources * like a 'JDBC connection pool' or a 'thread pool'. * <p /> * The important attributes of a resource are gathered in the <code>ResourceWrapper</code> class. * <p /> * You can easily handle bigger number of resources with good performance. * <p /> * To find out how to use it see the TestPool example in the main() method of this class. * <p /> * <pre> *    State chart of resource handling: * *      +<------- reserve() if(numIdle==0) ---------------------+ *      |                                                       | *      |     +<- reserve() --+        +<-preReserve() *-+      | *      |     | if(numIdle>0) |        |                 |      | *      |     |               |        |                 |      | *    #########               ##########                 ########## *   #         #             #          #               #          # *   #  busy   #             #  idle    #               #  undef   # *   #         #             #          #               #          # *    #########               ##########                 ########## *      |  |  |               | |  | | |                 | |  |  | *      |  |  |   Explicit    | |  | | |   Explicit      | |  |  | *      |  |  +-- release() ->+ |  | | +-- erase() ----->+ |  |  | *      |  |                    |  | |                     |  |  | *      |  +busyToIdleTimeout()>+  | +idleToEraseTimeout()>+  |  | *      |                          |                          |  | *      |                          +-- erase on max cycles *->+  | *      |                                                        | *      +--------- busyToEraseTimeout() since creation *-------->+ * * </pre> * There are three states: * <ul> *    <li>busy: The resource is in use *    </li> *    <li>idle: The resource is allocated and ready but not in use *    </li> *    <li>undef: The resource is not yet allocated or it is erased again *    </li> * </ul> * <p> * Note that state transitions marked with '*' are not yet implemented. * If you need one of them, code it and contribute it please. * <p> * You can choose which states you wish for your resource and how timeouts * are used to handle state transitions.<br /> * </p> * <p> * For example if you want to pool user login sessions and want to do * an auto logout after 60 minutes, you would use the busyToIdleTimeout and set it to 60*60*1000.<br /> * If a user is active you can refresh the session with busyRefresh().<br /> * Often you want to use your own generated sessionId as the primary key * for this resource, you can pass it as the instanceId argument to reserve(sessionId).<br /> * (See example [2] in this main() method) * </p> * <p> * If you want to pool JDBC connections, reserve() a connection before you do your query * and release() it immediately again. If you * want to close connections after peak usage, you could set a idleToEraseTimeout, * to erase your JDBC connection after some time not used (reducing the current pool size).<br /> * Note that in this example the connections are anonymous (all are logged in to the database * with the same user name), it is not important which you receive.<br /> * (See example [1] in this main() method) * </p> * <p> * For an implementation example see TestPoolManager.java * </p> * * <p>This code is derived from the org.jutils.pool package.</p> * @author "Marcel Ruff" <ruff@swand.lake.de> * @see org.xmlBlaster.util.pool.ResourceWrapper * @see org.xmlBlaster.test.classtest.TestPoolManager */public final class PoolManager{   /** Nice, unique name for logging output */   private String ME = "PoolManager";   /** A nice name for the generated id */   private String poolName = "Resource";   /** The callback into the using application, which needs to implement the interface I_PoolManager */   private I_PoolManager callback = null;   /** Holds busy resources */   private java.util.Hashtable busy = null;   /** Holds free resources */   private java.util.Vector idle = null;   /** Default maximum pool size (number of resources) */   private int maxInstances = 100;   /** Default maximum busy time of a resource, on timeout it changes state from 'busy' to 'idle' */   private long busyToIdleTimeout = 0;   /* Default maximum life span of a resource, on timeout it changes state from 'busy' to 'undef' (it is deleted) */   //private long busyToEraseTimeout = 0;   /** Default maximum idle span of a resource, on timeout it changes state from 'idle' to 'undef' (it is deleted) */   private long idleToEraseTimeout = 0;   /** Unique counter to generate IDs */   private long counter = 1;   /** Use this constant with the reserve() method, the PoolManager uses the hashCode() of your object */   public final static String USE_HASH_CODE = "h";   /** Use this constant with the reserve() method, the PoolManager uses the toString() of your object, if no toString() exists the object reference is used, e.g. "oracle.jdbc.driver.OracleConnection@443226" */   public final static String USE_OBJECT_REF = "o";   /** Use this constant with the reserve() method, the PoolManager generates a random, unique in universe session ID */   public final static String GENERATE_RANDOM = "r";   /** Triggers transitions */   private Timeout transitionTimer;   private final Object meetingPoint = new Object();   /**   * Create a new pool instance with the desired behavior.   * <p />   * Implementation:<br />   * There are two list in this class   * <ul>   *    <li>busy: Holds resources which are currently busy</li>   *    <li>idle: Holds resources in the free pool, waiting to be reused</li>   * </ul>   * If you ask for a new resource, this will move into the busy list<br />   * Is a resource released or a specified timeout occurred, it is moved into the idle list.   * <p />   * @param poolName       A nice name for this pool manager instance.   * @param callback       The interface 'I_PoolManager' callback   * @param maxInstances   Max. number of resources in this pool.   * @param busyToIdleTimeout Max. busy time of this resource in milli seconds<br />   *                       On timeout it changes state from 'busy' to 'idle'.<br />   *                       You can overwrite this value for each resource instance<br />   *                       0 switches it off<br />   *                       You get called back through I_PoolManager.busyToIdle() on timeout   *                       allowing you to code some specific handling.   * @param idleToEraseTimeout Max. idle time span of this resource in milli seconds<br />   *                     On timeout it changes state from 'idle' to 'undef' (it is deleted).<br />   *                     You can overwrite this value for each resource instance<br />   *                     0 switches it off<br />   *                     You get called back through I_PoolManager.toErased() on timeout   *                     allowing you to code some specific handling.   */   public PoolManager(String poolName, I_PoolManager callback, int maxInstances, long busyToIdleTimeout, long idleToEraseTimeout) {      this.poolName = poolName; // e.g. "SessionId"      this.callback = callback;      this.ME = poolName + "-PoolManager"; // e.g. "SessionId-PoolManager"      this.setMaxInstances(maxInstances);      this.setBusyToIdleTimeout(busyToIdleTimeout);      this.setIdleToEraseTimeout(idleToEraseTimeout);      this.busy = new java.util.Hashtable(maxInstances);      this.idle = new java.util.Vector(maxInstances);      /*        if (busyToIdleTimeout > 0 || idleToEraseTimeout > 0) {       System.err.println(ME + ": Created PoolManager with a maximum of " + maxInstances + " instances" +        " and a default busy recycling-timeout of " + TimeHelper.millisToNice(this.busyToIdleTimeout) +        " and a default idle recycling-timeout of " + TimeHelper.millisToNice(this.idleToEraseTimeout));        }        else       System.err.println(ME + ": Created PoolManager with a maximum of " + maxInstances + " instances without auto-recycling.");        */   }   public Timeout getTransistionTimer() {      if (this.transitionTimer == null) {         synchronized(this) {            if (this.transitionTimer == null)               this.transitionTimer = new Timeout("XmlBlaster.PoolManagerTimer");         }      }      return this.transitionTimer;   }   /**   * Set the maximum pool size.   * @param maxInstances How many resources are allowed   */   private void setMaxInstances(int maxInstances) {      this.maxInstances = maxInstances;   }   /**   * On timeout, the resource changes state from 'busy' to 'idle'.<br />   * @param busyToIdleTimeout Max. busy time of this resource in milli seconds<br />   *                       On timeout it changes state from 'busy' to 'idle'.<br />   *                       You can overwrite this value for each resource instance<br />   *                       0 switches it off   */   private void setBusyToIdleTimeout(long busyToIdleTimeout) {      if (busyToIdleTimeout > 0 && busyToIdleTimeout < 100) {         // System.err.println(ME + ": Setting minimum release timeout from " + busyToIdleTimeout + " to 100 milli seconds.");         this.busyToIdleTimeout = 100;      }      else         this.busyToIdleTimeout = busyToIdleTimeout;   }   /**   * Set the max. life span of the resources.   * @param idleToEraseTimeout Max. idle time of this resource in milli seconds<br />   *                       You can overwrite this value for each resource instance<br />   *                       0 switches it off   */   private void setIdleToEraseTimeout(long idleToEraseTimeout) {      if (idleToEraseTimeout > 0 && idleToEraseTimeout < 100) {         // System.err.println(ME + ": Setting minimum idleErase timeout from " + idleToEraseTimeout + " to 100 milli seconds.");         this.idleToEraseTimeout = 100;      }      else         this.idleToEraseTimeout = idleToEraseTimeout;   }   /**   * Get a new resource.   * <p />   * The life span is set to the default value of the pool.   * <p />   * The instance Id is random and unique generated.   * @exception XmlBlasterException Error with random generator   */   public ResourceWrapper reserve() throws XmlBlasterException {      return reserve(busyToIdleTimeout, idleToEraseTimeout, GENERATE_RANDOM);   }   /**   * Get a new resource.   * <p />   * The life span is set to the default value of the pool.   * <p />   * @param instanceId See description in other reserve() method.   * @exception XmlBlasterException Error with random generator   */   public ResourceWrapper reserve(String instanceId) throws XmlBlasterException {      return reserve(busyToIdleTimeout, idleToEraseTimeout, instanceId);   }   /**   * Get a new resource.   *   * @param localBusyToIdleTimeout Max. busy time of this resource in milli seconds,   *                       only for this current resource<br />   *                       Overwrite locally the default<br />   *                       0 switches busy timeout off   *   * @param localIdleToEraseTimeout Max. idle time of this resource in milli seconds,   *                       only for this current resource<br />   *                       Overwrite locally the default<br />   *                       0 switches idle timeout off   *   * @param instanceId If given and string length > 1, the delivered ID is used:   *             If in busy list found, this is returned, else a new is created.<br />   *             USE_HASH_CODE   - The PoolManager generates a simple one (hashCode())<br />   *             USE_OBJECT_REF  - The object reference is used<br />   *             GENERATE_RANDOM - The PoolManager generates a random, unique in universe session ID   *   * @return rw The resource handle (always != null)   *   * @exception XmlBlasterException Error with random generator   */   public ResourceWrapper reserve(long localBusyToIdleTimeout, long localIdleToEraseTimeout, String instanceId) throws XmlBlasterException {      synchronized (meetingPoint) {         ResourceWrapper rw = null;         if (instanceId != null && instanceId.length() > 1) {            rw = findBusySilent(instanceId);            if (rw != null) {               // System.out.println(ME + ": Reconnected to busy resource '" + instanceId + "' ...");               return rw;            }         }         if (idle.size() > 0) {            // System.out.println(ME + ": Resource is recycled from idle pool ...");            rw = (ResourceWrapper) idle.lastElement();            rw.init(createId(instanceId), rw.getResource(), localBusyToIdleTimeout, localIdleToEraseTimeout);            swap(rw, true);            // System.out.println(ME + ": Access on cached resource '" + rw.getInstanceId() + "' granted");            // dumpState(rw.getInstanceId());         }         else            if (busy.size() >= maxInstances) {               // CAUTION: ErrorCode.RESOURCE_EXHAUST is a well defined string which may not be changed, it is used from the caller to identify the situation               XmlBlasterException e = new XmlBlasterException("ResourceExhaust", "Sorry, " + maxInstances + " resources consumed, no more resources available");               e.changeErrorCode(ErrorCode.RESOURCE_EXHAUST);               throw e;            }            else {               instanceId = createId(instanceId);               Object resource = callback.toCreate(instanceId);               rw = new ResourceWrapper(this, instanceId, resource, localBusyToIdleTimeout, idleToEraseTimeout);               rw.toBusy();               busy.put(rw.getInstanceId(), rw);               // System.out.println(ME + ": Granted access to new resource '" + rw.getInstanceId() + "'");               // dumpState(rw.getInstanceId());            }         return rw;      }   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -