分享

common

 风_宇星 2014-05-06
  1. package org.apache.commons.pool.impl;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Collection;  
  5. import java.util.Iterator;  
  6. import java.util.LinkedList;  
  7. import java.util.List;  
  8. import java.util.NoSuchElementException;  
  9. import java.util.TimerTask;  
  10. import org.apache.commons.pool.BaseObjectPool;  
  11. import org.apache.commons.pool.ObjectPool;  
  12. import org.apache.commons.pool.PoolUtils;  
  13. import org.apache.commons.pool.PoolableObjectFactory;  
  14.   
  15. public class GenericObjectPool extends BaseObjectPool  
  16.   implements ObjectPool  
  17. {  
  18.   public static final byte WHEN_EXHAUSTED_FAIL = 0;  
  19.   public static final byte WHEN_EXHAUSTED_BLOCK = 1;  
  20.   public static final byte WHEN_EXHAUSTED_GROW = 2;  
  21.   public static final int DEFAULT_MAX_IDLE = 8;  
  22.   public static final int DEFAULT_MIN_IDLE = 0;  
  23.   public static final int DEFAULT_MAX_ACTIVE = 8;  
  24.   public static final byte DEFAULT_WHEN_EXHAUSTED_ACTION = 1;  
  25.   public static final boolean DEFAULT_LIFO = true;  
  26.   public static final long DEFAULT_MAX_WAIT = -1L;  
  27.   public static final boolean DEFAULT_TEST_ON_BORROW = false;  
  28.   public static final boolean DEFAULT_TEST_ON_RETURN = false;  
  29.   public static final boolean DEFAULT_TEST_WHILE_IDLE = false;  
  30.   public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;  
  31.   public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;  
  32.   public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1800000L;  
  33.   public static final long DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS = -1L;  
  34.   private int _maxIdle = 8;  
  35.   
  36.   private int _minIdle = 0;  
  37.   
  38.   private int _maxActive = 8;  
  39.   
  40.   private long _maxWait = -1L;  
  41.   
  42.   private byte _whenExhaustedAction = 1;  
  43.   
  44.   private volatile boolean _testOnBorrow = false;  
  45.   
  46.   private volatile boolean _testOnReturn = false;  
  47.   
  48.   private boolean _testWhileIdle = false;  
  49.   
  50.   private long _timeBetweenEvictionRunsMillis = -1L;  
  51.   
  52.   private int _numTestsPerEvictionRun = 3;  
  53.   
  54.   private long _minEvictableIdleTimeMillis = 1800000L;  
  55.   
  56.   private long _softMinEvictableIdleTimeMillis = -1L;  
  57.   
  58.   private boolean _lifo = true;  
  59.   
  60.   private CursorableLinkedList _pool = null;  
  61.   
  62.   private CursorableLinkedList.Cursor _evictionCursor = null;  
  63.   
  64.   private PoolableObjectFactory _factory = null;  
  65.   
  66.   private int _numActive = 0;  
  67.   
  68.   private Evictor _evictor = null;  
  69.   
  70.   private int _numInternalProcessing = 0;  
  71.   
  72.   private final LinkedList _allocationQueue = new LinkedList();  
  73.   
  74.   public GenericObjectPool()  
  75.   {  
  76.     this(null, 8, (byte)1, -1L, 8, 0, false, false, -1L, 3, 1800000L, false);  
  77.   }  
  78.   
  79.   public GenericObjectPool(PoolableObjectFactory factory)  
  80.   {  
  81.     this(factory, 8, (byte)1, -1L, 8, 0, false, false, -1L, 3, 1800000L, false);  
  82.   }  
  83.   
  84.   public GenericObjectPool(PoolableObjectFactory factory, Config config)  
  85.   {  
  86.     this(factory, config.maxActive, config.whenExhaustedAction, config.maxWait, config.maxIdle, config.minIdle, config.testOnBorrow, config.testOnReturn, config.timeBetweenEvictionRunsMillis, config.numTestsPerEvictionRun, config.minEvictableIdleTimeMillis, config.testWhileIdle, config.softMinEvictableIdleTimeMillis, config.lifo);  
  87.   }  
  88.   
  89.   public GenericObjectPool(PoolableObjectFactory factory, int maxActive)  
  90.   {  
  91.     this(factory, maxActive, (byte)1, -1L, 8, 0, false, false, -1L, 3, 1800000L, false);  
  92.   }  
  93.   
  94.   public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait)  
  95.   {  
  96.     this(factory, maxActive, whenExhaustedAction, maxWait, 8, 0, false, false, -1L, 3, 1800000L, false);  
  97.   }  
  98.   
  99.   public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, boolean testOnBorrow, boolean testOnReturn)  
  100.   {  
  101.     this(factory, maxActive, whenExhaustedAction, maxWait, 8, 0, testOnBorrow, testOnReturn, -1L, 3, 1800000L, false);  
  102.   }  
  103.   
  104.   public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle)  
  105.   {  
  106.     this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, 0, false, false, -1L, 3, 1800000L, false);  
  107.   }  
  108.   
  109.   public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn)  
  110.   {  
  111.     this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, 0, testOnBorrow, testOnReturn, -1L, 3, 1800000L, false);  
  112.   }  
  113.   
  114.   public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle)  
  115.   {  
  116.     this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, 0, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);  
  117.   }  
  118.   
  119.   public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int minIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle)  
  120.   {  
  121.     this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, minIdle, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle, -1L);  
  122.   }  
  123.   
  124.   public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int minIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle, long softMinEvictableIdleTimeMillis)  
  125.   {  
  126.     this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, minIdle, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle, softMinEvictableIdleTimeMillis, true);  
  127.   }  
  128.   
  129.   public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int minIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle, long softMinEvictableIdleTimeMillis, boolean lifo)  
  130.   {  
  131.     this._factory = factory;  
  132.     this._maxActive = maxActive;  
  133.     this._lifo = lifo;  
  134.     switch (whenExhaustedAction) {  
  135.     case 0:  
  136.     case 1:  
  137.     case 2:  
  138.       this._whenExhaustedAction = whenExhaustedAction;  
  139.       break;  
  140.     default:  
  141.       throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");  
  142.     }  
  143.     this._maxWait = maxWait;  
  144.     this._maxIdle = maxIdle;  
  145.     this._minIdle = minIdle;  
  146.     this._testOnBorrow = testOnBorrow;  
  147.     this._testOnReturn = testOnReturn;  
  148.     this._timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;  
  149.     this._numTestsPerEvictionRun = numTestsPerEvictionRun;  
  150.     this._minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;  
  151.     this._softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;  
  152.     this._testWhileIdle = testWhileIdle;  
  153.   
  154.     this._pool = new CursorableLinkedList();  
  155.     startEvictor(this._timeBetweenEvictionRunsMillis);  
  156.   }  
  157.   
  158.   public synchronized int getMaxActive()  
  159.   {  
  160.     return this._maxActive;  
  161.   }  
  162.   
  163.   public synchronized void setMaxActive(int maxActive)  
  164.   {  
  165.     this._maxActive = maxActive;  
  166.     allocate();  
  167.   }  
  168.   
  169.   public synchronized byte getWhenExhaustedAction()  
  170.   {  
  171.     return this._whenExhaustedAction;  
  172.   }  
  173.   
  174.   public synchronized void setWhenExhaustedAction(byte whenExhaustedAction)  
  175.   {  
  176.     switch (whenExhaustedAction) {  
  177.     case 0:  
  178.     case 1:  
  179.     case 2:  
  180.       this._whenExhaustedAction = whenExhaustedAction;  
  181.       allocate();  
  182.       break;  
  183.     default:  
  184.       throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");  
  185.     }  
  186.   }  
  187.   
  188.   public synchronized long getMaxWait()  
  189.   {  
  190.     return this._maxWait;  
  191.   }  
  192.   
  193.   public synchronized void setMaxWait(long maxWait)  
  194.   {  
  195.     this._maxWait = maxWait;  
  196.     allocate();  
  197.   }  
  198.   
  199.   public synchronized int getMaxIdle()  
  200.   {  
  201.     return this._maxIdle;  
  202.   }  
  203.   
  204.   public synchronized void setMaxIdle(int maxIdle)  
  205.   {  
  206.     this._maxIdle = maxIdle;  
  207.     allocate();  
  208.   }  
  209.   
  210.   public synchronized void setMinIdle(int minIdle)  
  211.   {  
  212.     this._minIdle = minIdle;  
  213.     allocate();  
  214.   }  
  215.   
  216.   public synchronized int getMinIdle()  
  217.   {  
  218.     return this._minIdle;  
  219.   }  
  220.   
  221.   public boolean getTestOnBorrow()  
  222.   {  
  223.     return this._testOnBorrow;  
  224.   }  
  225.   
  226.   public void setTestOnBorrow(boolean testOnBorrow)  
  227.   {  
  228.     this._testOnBorrow = testOnBorrow;  
  229.   }  
  230.   
  231.   public boolean getTestOnReturn()  
  232.   {  
  233.     return this._testOnReturn;  
  234.   }  
  235.   
  236.   public void setTestOnReturn(boolean testOnReturn)  
  237.   {  
  238.     this._testOnReturn = testOnReturn;  
  239.   }  
  240.   
  241.   public synchronized long getTimeBetweenEvictionRunsMillis()  
  242.   {  
  243.     return this._timeBetweenEvictionRunsMillis;  
  244.   }  
  245.   
  246.   public synchronized void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis)  
  247.   {  
  248.     this._timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;  
  249.     startEvictor(this._timeBetweenEvictionRunsMillis);  
  250.   }  
  251.   
  252.   public synchronized int getNumTestsPerEvictionRun()  
  253.   {  
  254.     return this._numTestsPerEvictionRun;  
  255.   }  
  256.   
  257.   public synchronized void setNumTestsPerEvictionRun(int numTestsPerEvictionRun)  
  258.   {  
  259.     this._numTestsPerEvictionRun = numTestsPerEvictionRun;  
  260.   }  
  261.   
  262.   public synchronized long getMinEvictableIdleTimeMillis()  
  263.   {  
  264.     return this._minEvictableIdleTimeMillis;  
  265.   }  
  266.   
  267.   public synchronized void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis)  
  268.   {  
  269.     this._minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;  
  270.   }  
  271.   
  272.   public synchronized long getSoftMinEvictableIdleTimeMillis()  
  273.   {  
  274.     return this._softMinEvictableIdleTimeMillis;  
  275.   }  
  276.   
  277.   public synchronized void setSoftMinEvictableIdleTimeMillis(long softMinEvictableIdleTimeMillis)  
  278.   {  
  279.     this._softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;  
  280.   }  
  281.   
  282.   public synchronized boolean getTestWhileIdle()  
  283.   {  
  284.     return this._testWhileIdle;  
  285.   }  
  286.   
  287.   public synchronized void setTestWhileIdle(boolean testWhileIdle)  
  288.   {  
  289.     this._testWhileIdle = testWhileIdle;  
  290.   }  
  291.   
  292.   public synchronized boolean getLifo()  
  293.   {  
  294.     return this._lifo;  
  295.   }  
  296.   
  297.   public synchronized void setLifo(boolean lifo)  
  298.   {  
  299.     this._lifo = lifo;  
  300.   }  
  301.   
  302.   public synchronized void setConfig(Config conf)  
  303.   {  
  304.     setMaxIdle(conf.maxIdle);  
  305.     setMinIdle(conf.minIdle);  
  306.     setMaxActive(conf.maxActive);  
  307.     setMaxWait(conf.maxWait);  
  308.     setWhenExhaustedAction(conf.whenExhaustedAction);  
  309.     setTestOnBorrow(conf.testOnBorrow);  
  310.     setTestOnReturn(conf.testOnReturn);  
  311.     setTestWhileIdle(conf.testWhileIdle);  
  312.     setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun);  
  313.     setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis);  
  314.     setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis);  
  315.     setSoftMinEvictableIdleTimeMillis(conf.softMinEvictableIdleTimeMillis);  
  316.     setLifo(conf.lifo);  
  317.     allocate();  
  318.   }  
  319.   
  320.   public Object borrowObject()  
  321.     throws Exception  
  322.   {  
  323.     long starttime = System.currentTimeMillis();  
  324.     Latch latch = new Latch(null);  
  325.     byte whenExhaustedAction;  
  326.     long maxWait;  
  327.     synchronized (this)  
  328.     {  
  329.       whenExhaustedAction = this._whenExhaustedAction;  
  330.       maxWait = this._maxWait;  
  331.   
  332.       this._allocationQueue.add(latch);  
  333.   
  334.       allocate();  
  335.     }  
  336.     while (true)  
  337.     {  
  338.       synchronized (this) {  
  339.         assertOpen();  
  340.       }  
  341.   
  342.       if (latch.getPair() == null)  
  343.       {  
  344.         if (!latch.mayCreate())  
  345.         {  
  346.           switch (whenExhaustedAction)  
  347.           {  
  348.           case 2:  
  349.             synchronized (this)  
  350.             {  
  351.               if ((latch.getPair() == null) && (!latch.mayCreate())) {  
  352.                 this._allocationQueue.remove(latch);  
  353.                 this._numInternalProcessing += 1;  
  354.               }  
  355.             }  
  356.             break;  
  357.           case 0:  
  358.             synchronized (this)  
  359.             {  
  360.               if ((latch.getPair() == null) && (latch.mayCreate())) {  
  361.                 break label497;  
  362.               }  
  363.               this._allocationQueue.remove(latch);  
  364.             }  
  365.             throw new NoSuchElementException("Pool exhausted");  
  366.           case 1:  
  367.             try {  
  368.               synchronized (latch)  
  369.               {  
  370.                 if ((latch.getPair() == null) && (!latch.mayCreate())) {  
  371.                   if (maxWait <= 0L) {  
  372.                     latch.wait();  
  373.                   }  
  374.                   else  
  375.                   {  
  376.                     long elapsed = System.currentTimeMillis() - starttime;  
  377.                     long waitTime = maxWait - elapsed;  
  378.                     if (waitTime > 0L)  
  379.                     {  
  380.                       latch.wait(waitTime);  
  381.                     }  
  382.                   }  
  383.                 }  
  384.                 else break label497;   
  385.               }  
  386.             }  
  387.             catch (InterruptedException e)  
  388.             {  
  389.               synchronized (this)  
  390.               {  
  391.                 if ((latch.getPair() == null) && (!latch.mayCreate()))  
  392.                 {  
  393.                   this._allocationQueue.remove(latch);  
  394.                 }  
  395.                 else break label497;  
  396.               }  
  397.   
  398.               Thread.currentThread().interrupt();  
  399.               throw e;  
  400.             }  
  401.             if ((maxWait <= 0L) || (System.currentTimeMillis() - starttime < maxWait)) continue;  
  402.             synchronized (this)  
  403.             {  
  404.               if ((latch.getPair() == null) && (!latch.mayCreate()))  
  405.               {  
  406.                 this._allocationQueue.remove(latch);  
  407.               }  
  408.               else break label497;  
  409.             }  
  410.   
  411.             throw new NoSuchElementException("Timeout waiting for idle object");  
  412.           default:  
  413.             throw new IllegalArgumentException("WhenExhaustedAction property " + whenExhaustedAction + " not recognized.");  
  414.           }  
  415.         }  
  416.       }  
  417.       else  
  418.       {  
  419.         label497: boolean newlyCreated = false;  
  420.         if (null == latch.getPair()) {  
  421.           try {  
  422.             Object obj = this._factory.makeObject();  
  423.             latch.setPair(new GenericKeyedObjectPool.ObjectTimestampPair(obj));  
  424.             newlyCreated = true;  
  425.           } finally {  
  426.             if (!newlyCreated)  
  427.             {  
  428.               synchronized (this) {  
  429.                 this._numInternalProcessing -= 1;  
  430.   
  431.                 allocate();  
  432.               }  
  433.             }  
  434.           }  
  435.         }  
  436.         try  
  437.         {  
  438.           this._factory.activateObject(latch.getPair().value);  
  439.           if ((this._testOnBorrow) && (!this._factory.validateObject(latch.getPair().value)))  
  440.           {  
  441.             throw new Exception("ValidateObject failed");  
  442.           }  
  443.           synchronized (this) {  
  444.             this._numInternalProcessing -= 1;  
  445.             this._numActive += 1;  
  446.           }  
  447.           return latch.getPair().value;  
  448.         }  
  449.         catch (Throwable e) {  
  450.           PoolUtils.checkRethrow(e);  
  451.           try  
  452.           {  
  453.             this._factory.destroyObject(latch.getPair().value);  
  454.           } catch (Throwable e2) {  
  455.             PoolUtils.checkRethrow(e2);  
  456.           }  
  457.   
  458.           synchronized (this) {  
  459.             this._numInternalProcessing -= 1;  
  460.             if (!newlyCreated) {  
  461.               latch.reset();  
  462.               this._allocationQueue.add(0, latch);  
  463.             }  
  464.             allocate();  
  465.           }  
  466.           if (newlyCreated)  
  467.             throw new NoSuchElementException("Could not create a validated object, cause: " + e.getMessage());  
  468.         }  
  469.       }  
  470.     }  
  471.   }  
  472.   
  473.   private synchronized void allocate()  
  474.   {  
  475.     if (isClosed()) return;  
  476.   
  477.     while ((!this._pool.isEmpty()) && (!this._allocationQueue.isEmpty())) {  
  478.       Latch latch = (Latch)this._allocationQueue.removeFirst();  
  479.       latch.setPair((GenericKeyedObjectPool.ObjectTimestampPair)this._pool.removeFirst());  
  480.       this._numInternalProcessing += 1;  
  481.       synchronized (latch) {  
  482.         latch.notify();  
  483.       }  
  484.   
  485.     }  
  486.   
  487.     while ((!this._allocationQueue.isEmpty()) && ((this._maxActive < 0) || (this._numActive + this._numInternalProcessing < this._maxActive))) {  
  488.       Latch latch = (Latch)this._allocationQueue.removeFirst();  
  489.       latch.setMayCreate(true);  
  490.       this._numInternalProcessing += 1;  
  491.       synchronized (latch) {  
  492.         latch.notify();  
  493.       }  
  494.     }  
  495.   }  
  496.   
  497.   public void invalidateObject(Object obj)  
  498.     throws Exception  
  499.   {  
  500.     try  
  501.     {  
  502.       if (this._factory != null)  
  503.         this._factory.destroyObject(obj);  
  504.     }  
  505.     finally {  
  506.       synchronized (this) {  
  507.         this._numActive -= 1;  
  508.         allocate();  
  509.       }  
  510.     }  
  511.   }  
  512.   
  513.   public void clear()  
  514.   {  
  515.     List toDestroy = new ArrayList();  
  516.   
  517.     synchronized (this) {  
  518.       toDestroy.addAll(this._pool);  
  519.       this._numInternalProcessing += this._pool._size;  
  520.       this._pool.clear();  
  521.     }  
  522.     destroy(toDestroy, this._factory);  
  523.   }  
  524.   
  525.   private void destroy(Collection c, PoolableObjectFactory factory)  
  526.   {  
  527.     for (Iterator it = c.iterator(); it.hasNext(); )  
  528.       try {  
  529.         factory.destroyObject(((GenericKeyedObjectPool.ObjectTimestampPair)it.next()).value);  
  530.       } catch (Exception e) {  
  531.       }  
  532.       finally {  
  533.         synchronized (this) {  
  534.           this._numInternalProcessing -= 1;  
  535.           allocate();  
  536.         }  
  537.       }  
  538.   }  
  539.   
  540.   public synchronized int getNumActive()  
  541.   {  
  542.     return this._numActive;  
  543.   }  
  544.   
  545.   public synchronized int getNumIdle()  
  546.   {  
  547.     return this._pool.size();  
  548.   }  
  549.   
  550.   public void returnObject(Object obj)  
  551.     throws Exception  
  552.   {  
  553.     try  
  554.     {  
  555.       addObjectToPool(obj, true);  
  556.     } catch (Exception e) {  
  557.       if (this._factory != null) {  
  558.         try {  
  559.           this._factory.destroyObject(obj);  
  560.         }  
  561.         catch (Exception e2)  
  562.         {  
  563.         }  
  564.   
  565.         synchronized (this) {  
  566.           this._numActive -= 1;  
  567.           allocate();  
  568.         }  
  569.       }  
  570.     }  
  571.   }  
  572.   
  573.   private void addObjectToPool(Object obj, boolean decrementNumActive)  
  574.     throws Exception  
  575.   {  
  576.     boolean success = true;  
  577.     if ((this._testOnReturn) && (!this._factory.validateObject(obj)))  
  578.       success = false;  
  579.     else {  
  580.       this._factory.passivateObject(obj);  
  581.     }  
  582.   
  583.     boolean shouldDestroy = !success;  
  584.   
  585.     synchronized (this) {  
  586.       if (isClosed()) {  
  587.         shouldDestroy = true;  
  588.       }  
  589.       else if ((this._maxIdle >= 0) && (this._pool.size() >= this._maxIdle)) {  
  590.         shouldDestroy = true;  
  591.       } else if (success)  
  592.       {  
  593.         if (this._lifo)  
  594.           this._pool.addFirst(new GenericKeyedObjectPool.ObjectTimestampPair(obj));  
  595.         else {  
  596.           this._pool.addLast(new GenericKeyedObjectPool.ObjectTimestampPair(obj));  
  597.         }  
  598.         if (decrementNumActive) {  
  599.           this._numActive -= 1;  
  600.         }  
  601.         allocate();  
  602.       }  
  603.   
  604.     }  
  605.   
  606.     if (shouldDestroy) {  
  607.       try {  
  608.         this._factory.destroyObject(obj);  
  609.       }  
  610.       catch (Exception e)  
  611.       {  
  612.       }  
  613.       if (decrementNumActive)  
  614.         synchronized (this) {  
  615.           this._numActive -= 1;  
  616.           allocate();  
  617.         }  
  618.     }  
  619.   }  
  620.   
  621.   public void close()  
  622.     throws Exception  
  623.   {  
  624.     super.close();  
  625.     synchronized (this) {  
  626.       clear();  
  627.       startEvictor(-1L);  
  628.     }  
  629.   }  
  630.   
  631.   /** @deprecated */  
  632.   public void setFactory(PoolableObjectFactory factory)  
  633.     throws IllegalStateException  
  634.   {  
  635.     List toDestroy = new ArrayList();  
  636.     PoolableObjectFactory oldFactory = this._factory;  
  637.     synchronized (this) {  
  638.       assertOpen();  
  639.       if (0 < getNumActive()) {  
  640.         throw new IllegalStateException("Objects are already active");  
  641.       }  
  642.       toDestroy.addAll(this._pool);  
  643.       this._numInternalProcessing += this._pool._size;  
  644.       this._pool.clear();  
  645.   
  646.       this._factory = factory;  
  647.     }  
  648.     destroy(toDestroy, oldFactory);  
  649.   }  
  650.   
  651.   public void evict()  
  652.     throws Exception  
  653.   {  
  654.     assertOpen();  
  655.     synchronized (this) {  
  656.       if (this._pool.isEmpty()) {  
  657.         return;  
  658.       }  
  659.       if (null == this._evictionCursor) {  
  660.         this._evictionCursor = this._pool.cursor(this._lifo ? this._pool.size() : 0);  
  661.       }  
  662.     }  
  663.   
  664.     int i = 0; for (int m = getNumTests(); i < m; i++)  
  665.     {  
  666.       GenericKeyedObjectPool.ObjectTimestampPair pair;  
  667.       synchronized (this) {  
  668.         if (((this._lifo) && (!this._evictionCursor.hasPrevious())) || ((!this._lifo) && (!this._evictionCursor.hasNext())))  
  669.         {  
  670.           this._evictionCursor.close();  
  671.           this._evictionCursor = this._pool.cursor(this._lifo ? this._pool.size() : 0);  
  672.         }  
  673.   
  674.         pair = this._lifo ? (GenericKeyedObjectPool.ObjectTimestampPair)this._evictionCursor.previous() : (GenericKeyedObjectPool.ObjectTimestampPair)this._evictionCursor.next();  
  675.   
  676.         this._evictionCursor.remove();  
  677.         this._numInternalProcessing += 1;  
  678.       }  
  679.   
  680.       boolean removeObject = false;  
  681.       long idleTimeMilis = System.currentTimeMillis() - pair.tstamp;  
  682.       if ((getMinEvictableIdleTimeMillis() > 0L) && (idleTimeMilis > getMinEvictableIdleTimeMillis()))  
  683.       {  
  684.         removeObject = true;  
  685.       } else if ((getSoftMinEvictableIdleTimeMillis() > 0L) && (idleTimeMilis > getSoftMinEvictableIdleTimeMillis()) && (getNumIdle() + 1 > getMinIdle()))  
  686.       {  
  687.         removeObject = true;  
  688.       }  
  689.       if ((getTestWhileIdle()) && (!removeObject)) {  
  690.         boolean active = false;  
  691.         try {  
  692.           this._factory.activateObject(pair.value);  
  693.           active = true;  
  694.         } catch (Exception e) {  
  695.           removeObject = true;  
  696.         }  
  697.         if (active) {  
  698.           if (!this._factory.validateObject(pair.value))  
  699.             removeObject = true;  
  700.           else {  
  701.             try {  
  702.               this._factory.passivateObject(pair.value);  
  703.             } catch (Exception e) {  
  704.               removeObject = true;  
  705.             }  
  706.           }  
  707.         }  
  708.       }  
  709.   
  710.       if (removeObject)  
  711.         try {  
  712.           this._factory.destroyObject(pair.value);  
  713.         }  
  714.         catch (Exception e)  
  715.         {  
  716.         }  
  717.       synchronized (this) {  
  718.         if (!removeObject) {  
  719.           this._evictionCursor.add(pair);  
  720.           if (this._lifo)  
  721.           {  
  722.             this._evictionCursor.previous();  
  723.           }  
  724.         }  
  725.         this._numInternalProcessing -= 1;  
  726.       }  
  727.     }  
  728.   }  
  729.   
  730.   private void ensureMinIdle()  
  731.     throws Exception  
  732.   {  
  733.     int objectDeficit = calculateDeficit(false);  
  734.     for (int j = 0; (j < objectDeficit) && (calculateDeficit(true) > 0); j++)  
  735.       try {  
  736.         addObject();  
  737.       } finally {  
  738.         synchronized (this) {  
  739.           this._numInternalProcessing -= 1;  
  740.           allocate();  
  741.         }  
  742.       }  
  743.   }  
  744.   
  745.   private synchronized int calculateDeficit(boolean incrementInternal)  
  746.   {  
  747.     int objectDeficit = getMinIdle() - getNumIdle();  
  748.     if (this._maxActive > 0) {  
  749.       int growLimit = Math.max(0, getMaxActive() - getNumActive() - getNumIdle() - this._numInternalProcessing);  
  750.   
  751.       objectDeficit = Math.min(objectDeficit, growLimit);  
  752.     }  
  753.     if ((incrementInternal) && (objectDeficit > 0)) {  
  754.       this._numInternalProcessing += 1;  
  755.     }  
  756.     return objectDeficit;  
  757.   }  
  758.   
  759.   public void addObject()  
  760.     throws Exception  
  761.   {  
  762.     assertOpen();  
  763.     if (this._factory == null) {  
  764.       throw new IllegalStateException("Cannot add objects without a factory.");  
  765.     }  
  766.     Object obj = this._factory.makeObject();  
  767.     try {  
  768.       assertOpen();  
  769.       addObjectToPool(obj, false);  
  770.     } catch (IllegalStateException ex) {  
  771.       try {  
  772.         this._factory.destroyObject(obj);  
  773.       }  
  774.       catch (Exception ex2) {  
  775.       }  
  776.       throw ex;  
  777.     }  
  778.   }  
  779.   
  780.   protected synchronized void startEvictor(long delay)  
  781.   {  
  782.     if (null != this._evictor) {  
  783.       EvictionTimer.cancel(this._evictor);  
  784.       this._evictor = null;  
  785.     }  
  786.     if (delay > 0L) {  
  787.       this._evictor = new Evictor(null);  
  788.       EvictionTimer.schedule(this._evictor, delay, delay);  
  789.     }  
  790.   }  
  791.   
  792.   synchronized String debugInfo()  
  793.   {  
  794.     StringBuffer buf = new StringBuffer();  
  795.     buf.append("Active: ").append(getNumActive()).append("\n");  
  796.     buf.append("Idle: ").append(getNumIdle()).append("\n");  
  797.     buf.append("Idle Objects:\n");  
  798.     Iterator it = this._pool.iterator();  
  799.     long time = System.currentTimeMillis();  
  800.     while (it.hasNext()) {  
  801.       GenericKeyedObjectPool.ObjectTimestampPair pair = (GenericKeyedObjectPool.ObjectTimestampPair)it.next();  
  802.       buf.append("\t").append(pair.value).append("\t").append(time - pair.tstamp).append("\n");  
  803.     }  
  804.     return buf.toString();  
  805.   }  
  806.   
  807.   private int getNumTests()  
  808.   {  
  809.     if (this._numTestsPerEvictionRun >= 0) {  
  810.       return Math.min(this._numTestsPerEvictionRun, this._pool.size());  
  811.     }  
  812.     return (int)Math.ceil(this._pool.size() / Math.abs(this._numTestsPerEvictionRun));  
  813.   }  
  814.   
  815.   private static final class Latch  
  816.   {  
  817.     private GenericKeyedObjectPool.ObjectTimestampPair _pair;  
  818.     private boolean _mayCreate = false;  
  819.   
  820.     private Latch()  
  821.     {  
  822.     }  
  823.   
  824.     private synchronized GenericKeyedObjectPool.ObjectTimestampPair getPair() {  
  825.       return this._pair;  
  826.     }  
  827.   
  828.     private synchronized void setPair(GenericKeyedObjectPool.ObjectTimestampPair pair)  
  829.     {  
  830.       this._pair = pair;  
  831.     }  
  832.   
  833.     private synchronized boolean mayCreate()  
  834.     {  
  835.       return this._mayCreate;  
  836.     }  
  837.   
  838.     private synchronized void setMayCreate(boolean mayCreate)  
  839.     {  
  840.       this._mayCreate = mayCreate;  
  841.     }  
  842.   
  843.     private synchronized void reset()  
  844.     {  
  845.       this._pair = null;  
  846.       this._mayCreate = false;  
  847.     }  
  848.   
  849.     Latch(GenericObjectPool.1 x0)  
  850.     {  
  851.       this();  
  852.     }  
  853.   }  
  854.   
  855.   public static class Config  
  856.   {  
  857.     public int maxIdle = 8;  
  858.   
  859.     public int minIdle = 0;  
  860.   
  861.     public int maxActive = 8;  
  862.   
  863.     public long maxWait = -1L;  
  864.   
  865.     public byte whenExhaustedAction = 1;  
  866.   
  867.     public boolean testOnBorrow = false;  
  868.   
  869.     public boolean testOnReturn = false;  
  870.   
  871.     public boolean testWhileIdle = false;  
  872.   
  873.     public long timeBetweenEvictionRunsMillis = -1L;  
  874.   
  875.     public int numTestsPerEvictionRun = 3;  
  876.   
  877.     public long minEvictableIdleTimeMillis = 1800000L;  
  878.   
  879.     public long softMinEvictableIdleTimeMillis = -1L;  
  880.   
  881.     public boolean lifo = true;  
  882.   }  
  883.   
  884.   private class Evictor extends TimerTask  
  885.   {  
  886.     private Evictor()  
  887.     {  
  888.     }  
  889.   
  890.     public void run()  
  891.     {  
  892.       try  
  893.       {  
  894.         GenericObjectPool.this.evict();  
  895.       }  
  896.       catch (Exception e)  
  897.       {  
  898.       }  
  899.       catch (OutOfMemoryError oome) {  
  900.         oome.printStackTrace(System.err);  
  901.       }  
  902.       try {  
  903.         GenericObjectPool.this.ensureMinIdle();  
  904.       }  
  905.       catch (Exception e)  
  906.       {  
  907.       }  
  908.     }  
  909.   
  910.     Evictor(GenericObjectPool.1 x1)  
  911.     {  
  912.       this();  
  913.     }  
  914.   }  
  915. }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多