pool(四)——EvictionTimer
来源:互联网 发布:mac 穿越火线下载安装 编辑:程序博客网 时间:2024/05/21 10:56
1.BaseGenericObjectPool的startEvictor
/** * <p>Starts the evictor with the given delay. If there is an evictor * running when this method is called, it is stopped and replaced with a * new evictor with the specified delay.</p> * * <p>This method needs to be final, since it is called from a constructor. * See POOL-195.</p> * * @param delay time in milliseconds before start and between eviction runs */ final void startEvictor(long delay) { synchronized (evictionLock) { if (null != evictor) { EvictionTimer.cancel(evictor); evictor = null; evictionIterator = null; } if (delay > 0) { evictor = new Evictor(); EvictionTimer.schedule(evictor, delay, delay); } } }这里会用EvictionTimer去执行Evictor这个任务。
2.EvictionTimer
对上一篇说的Timer进行了包装/** * Add the specified eviction task to the timer. Tasks that are added with a * call to this method *must* call {@link #cancel(TimerTask)} to cancel the * task to prevent memory and/or thread leaks in application server * environments. * @param task Task to be scheduled * @param delay Delay in milliseconds before task is executed * @param period Time in milliseconds between executions */ static synchronized void schedule(TimerTask task, long delay, long period) { if (null == _timer) { // Force the new Timer thread to be created with a context class // loader set to the class loader that loaded this library ClassLoader ccl = AccessController.doPrivileged( new PrivilegedGetTccl()); try { AccessController.doPrivileged(new PrivilegedSetTccl( EvictionTimer.class.getClassLoader())); _timer = new Timer("commons-pool-EvictionTimer", true); } finally { AccessController.doPrivileged(new PrivilegedSetTccl(ccl)); } } _usageCount++; _timer.schedule(task, delay, period); }
3.Evictor
/** * The idle object evictor {@link TimerTask}. * * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis */ class Evictor extends TimerTask { /** * Run pool maintenance. Evict objects qualifying for eviction and then * ensure that the minimum number of idle instances are available. * Since the Timer that invokes Evictors is shared for all Pools but * pools may exist in different class loaders, the Evictor ensures that * any actions taken are under the class loader of the factory * associated with the pool. */ @Override public void run() { ClassLoader savedClassLoader = Thread.currentThread().getContextClassLoader(); try { // Set the class loader for the factory Thread.currentThread().setContextClassLoader( factoryClassLoader); // Evict from the pool try { evict(); } catch(Exception e) { swallowException(e); } catch(OutOfMemoryError oome) { // Log problem but give evictor thread a chance to continue // in case error is recoverable oome.printStackTrace(System.err); } // Re-create idle instances. try { ensureMinIdle(); } catch (Exception e) { swallowException(e); } } finally { // Restore the previous CCL Thread.currentThread().setContextClassLoader(savedClassLoader); } } }该类是TimerTask的子类,run方法有两个主要功能,evict和ensureMinIdle,一个是清除对象池中过期的对象,一个是保证对象池中始终有个数为minIdle个对象。
4.evict方法
该方法中使用了EvictionPolicy来判断是对象池中的对象是否过期了。
默认的实现是:
public class DefaultEvictionPolicy<T> implements EvictionPolicy<T> { @Override public boolean evict(EvictionConfig config, PooledObject<T> underTest, int idleCount) { if ((config.getIdleSoftEvictTime() < underTest.getIdleTimeMillis() && config.getMinIdle() < idleCount) || config.getIdleEvictTime() < underTest.getIdleTimeMillis()) { return true; } return false; }}如果结果是true,把该对象从对象池中移除,并计数加一。
/** * Destroys a wrapped pooled object. * * @param toDestory The wrapped pooled object to destroy * * @throws Exception If the factory fails to destroy the pooled object * cleanly */ private void destroy(PooledObject<T> toDestory) throws Exception { toDestory.invalidate(); idleObjects.remove(toDestory); allObjects.remove(toDestory.getObject()); try { factory.destroyObject(toDestory); } finally { destroyedCount.incrementAndGet(); createCount.decrementAndGet(); } }
5.ensureMinIdle
/** * Tries to ensure that {@code idleCount} idle instances exist in the pool. * <p> * Creates and adds idle instances until either {@link #getNumIdle()} reaches {@code idleCount} * or the total number of objects (idle, checked out, or being created) reaches * {@link #getMaxTotal()}. If {@code always} is false, no instances are created unless * there are threads waiting to check out instances from the pool. * * @param idleCount the number of idle instances desired * @param always true means create instances even if the pool has no threads waiting * @throws Exception if the factory's makeObject throws */ private void ensureIdle(int idleCount, boolean always) throws Exception { if (idleCount < 1 || isClosed() || (!always && !idleObjects.hasTakeWaiters())) { return; } while (idleObjects.size() < idleCount) { PooledObject<T> p = create(); if (p == null) { // Can't create objects, no reason to think another call to // create will work. Give up. break; } if (getLifo()) { idleObjects.addFirst(p); } else { idleObjects.addLast(p); } } }保证 {@link GenericObjectPool#idleObjects} 对象的size和{@link GenericObjectPool#getMinIdle}一致。
但是如果 {@link GenericObjectPool#createCount} == {@link GenericObjectPool#maxTotal},{@link GenericObjectPool#create} 方法就无法继续创建对象了。
/** * Attempts to create a new wrapped pooled object. * <p> * If there are {@link #getMaxTotal()} objects already in circulation * or in process of being created, this method returns null. * * @return The new wrapped pooled object * * @throws Exception if the object factory's {@code makeObject} fails */ private PooledObject<T> create() throws Exception { int localMaxTotal = getMaxTotal(); long newCreateCount = createCount.incrementAndGet(); if (localMaxTotal > -1 && newCreateCount > localMaxTotal || newCreateCount > Integer.MAX_VALUE) { createCount.decrementAndGet(); return null; } final PooledObject<T> p; try { p = factory.makeObject(); } catch (Exception e) { createCount.decrementAndGet(); throw e; } AbandonedConfig ac = this.abandonedConfig; if (ac != null && ac.getLogAbandoned()) { p.setLogAbandoned(true); } createdCount.incrementAndGet(); allObjects.put(p.getObject(), p); return p; }
0 0
- pool(四)——EvictionTimer
- Exception in thread “commons-pool-EvictionTimer”
- pool(一)——入门
- pool(三)——Timer
- pool(五)——BasicDataSource
- pool(六)——JedisPool
- library cache —— latch: shared pool
- pool(二)——动手入门
- python 多进程 —— multiprocessing.Pool
- Oracle——Default pool 之cache特性 以及 测试default pool使用效果实验分享
- 关于shared pool的深入探讨(四)
- VC++多线程应用--代码清单四:POOL
- POOL
- pool
- Pool
- C#多线程实现方法——线程池(Thread Pool)
- [Boost基础]内存管理——内存池pool库
- 10 table—index—inode:深入buffer pool
- 观察者模式-猫捉老鼠(委托与事件)
- RecyclerView 添加点击事件的几种方法
- 死锁的定义、产生原因、必要条件、避免死锁和解除死锁的方法
- Hibernate总结(三)--之一级缓存
- HDU(1715)大菲波数
- pool(四)——EvictionTimer
- POJ 1978 Hanafuda Shuffle
- 监听ContentProvider数据改变
- AndroidStudio默认继承V7包下的AppCompatActivity
- jQuery——遍历
- jquery validate 比较两个input输入框的值的大小
- nginx as Database Load Balancer for MySQL or MariaDB Galera Cluster
- mfc树控件Tree Control 修改添加删除节点
- 深入理解ButterKnife