博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
commons-pool2源码分析evictor
阅读量:6251 次
发布时间:2019-06-22

本文共 9506 字,大约阅读时间需要 31 分钟。

hot3.png

续 ,commons-pool2中有个驱逐机制Evictor定时任务,看其实怎么启动的 :

143716_wypz_1445156.png

在初始化对象池GenericObjectPool的时候对调用父类的startEvictor方法,父类初始化一个TimerTask的子类Evictor交由Timer定时执行,Evictor中的run方法最终还是调用当前对象池的evict方法和ensureMinIdle方法,下面看具体的代码分析:

GenericObjectPool

    public GenericObjectPool(PooledObjectFactory
 factory,            GenericObjectPoolConfig config) {        ...//省略        startEvictor(getTimeBetweenEvictionRunsMillis());//配置timeBetweenEvictionRunsMillis    }

BaseGenericObjectPool

    final void startEvictor(long delay) {        synchronized (evictionLock) {            if (null != evictor) {                EvictionTimer.cancel(evictor);                evictor = null;                evictionIterator = null;            }            //timeBetweenEvictionRunsMillis>0才会启动            if (delay > 0) {                evictor = new Evictor();                EvictionTimer.schedule(evictor, delay, delay);            }        }    }

BaseGenericObjectPool的内部类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 {                if (factoryClassLoader != null) {                    // Set the class loader for the factory                    ClassLoader cl = factoryClassLoader.get();                    if (cl == null) {                        // The pool has been dereferenced and the class loader                        // GC'd. Cancel this timer so the pool can be GC'd as                        // well.                        cancel();                        return;                    }                    Thread.currentThread().setContextClassLoader(cl);                }                // 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);            }        }    }

以GenericObjectPool为例看evict()和ensureMinIdle()

    public void evict() throws Exception {        assertOpen();        if (idleObjects.size() > 0) {//如果空闲数大于0            PooledObject
 underTest = null;            EvictionPolicy
 evictionPolicy = getEvictionPolicy();//evict的策略            synchronized (evictionLock) {                EvictionConfig evictionConfig = new EvictionConfig(                        getMinEvictableIdleTimeMillis(),                        getSoftMinEvictableIdleTimeMillis(),                        getMinIdle());//驱逐配置,后面驱逐策略需要用到                boolean testWhileIdle = getTestWhileIdle();//空闲时检查开关                //getNumTests为每次检查对象数量                for (int i = 0, m = getNumTests(); i < m; i++) {                    if (evictionIterator == null || !evictionIterator.hasNext()) {                        evictionIterator = new EvictionIterator(idleObjects);                    }                    if (!evictionIterator.hasNext()) {                        // Pool exhausted, nothing to do here                        return;                    }                    try {                        underTest = evictionIterator.next();                    } catch (NoSuchElementException nsee) {                        // Object was borrowed in another thread                        // Don't count this as an eviction test so reduce i;                        i--;                        evictionIterator = null;                        continue;                    }                    //修改状态                    if (!underTest.startEvictionTest()) {                        // Object was borrowed in another thread                        // Don't count this as an eviction test so reduce i;                        i--;                        continue;                    }                    // User provided eviction policy could throw all sorts of                    // crazy exceptions. Protect against such an exception                    // killing the eviction thread.                    boolean evict;                    try {                        //根据策略进行判断是否需要驱逐,默认策略DefaultEvictionPolicy                        evict = evictionPolicy.evict(evictionConfig, underTest,                                idleObjects.size());                    } catch (Throwable t) {                        // Slightly convoluted as SwallowedExceptionListener                        // uses Exception rather than Throwable                        PoolUtils.checkRethrow(t);                        swallowException(new Exception(t));                        // Don't evict on error conditions                        evict = false;                    }                    if (evict) {//需要驱逐的对象直接销毁                        destroy(underTest);                        destroyedByEvictorCount.incrementAndGet();                    } else {                        if (testWhileIdle) {//如果空闲时检查                            boolean active = false;                            try {                                factory.activateObject(underTest);//激活                                active = true;                            } catch (Exception e) {                                destroy(underTest);//激活失败就销毁                                destroyedByEvictorCount.incrementAndGet();                            }                            if (active) {                                if (!factory.validateObject(underTest)) {//验证                                    destroy(underTest);//验证失败就销毁                                    destroyedByEvictorCount.incrementAndGet();                                } else {                                    try {                                        factory.passivateObject(underTest);//验证成功就钝化                                    } catch (Exception e) {                                        destroy(underTest);                                        destroyedByEvictorCount.incrementAndGet();                                    }                                }                            }                        }                        //驱逐测试结束,修改状态                        if (!underTest.endEvictionTest(idleObjects)) {                            // TODO - May need to add code here once additional                            // states are used                        }                    }                }            }        }        //移除废弃对象        AbandonedConfig ac = this.abandonedConfig;        if (ac != null && ac.getRemoveAbandonedOnMaintenance()) {            removeAbandoned(ac);        }    }    private void ensureIdle(int idleCount, boolean always) throws Exception {        if (idleCount < 1 || isClosed() || (!always && !idleObjects.hasTakeWaiters())) {            return;        }        //如果空闲数小于最小阀值就一直创建对象        while (idleObjects.size() < idleCount) {            PooledObject
 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);            }        }        if (isClosed()) {            // Pool closed while object was being added to idle objects.            // Make sure the returned object is destroyed rather than left            // in the idle object pool (which would effectively be a leak)            clear();        }    }

DefaultEvictionPolicy

public class DefaultEvictionPolicy
 implements EvictionPolicy
 {    @Override    public boolean evict(EvictionConfig config, PooledObject
 underTest,            int idleCount) {        //1.如果对象空闲时间大于IdleSoftEvictTime并且空闲数量大于最小空闲阀值        //2.如果对象空闲时间大于IdleEvictTime        //满足上面的一种情况就返回true        if ((config.getIdleSoftEvictTime() < underTest.getIdleTimeMillis() &&                config.getMinIdle() < idleCount) ||                config.getIdleEvictTime() < underTest.getIdleTimeMillis()) {            return true;        }        return false;    }}//IdleEvictTime比IdleSoftEvictTime要严格一点,所以正常配置IdleEvictTime>IdleSoftEvictTime这两个配置在BaseObjectPoolConfig中的体现://IdleEvictTime对应配置为:minEvictableIdleTimeMillis//IdleSoftEvictTime对应配置为softMinEvictableIdleTimeMillis

转载于:https://my.oschina.net/chengxiaoyuan/blog/608084

你可能感兴趣的文章
LogBoy运行截图
查看>>
string.Format字符串格式说明
查看>>
关于配置Tomcat的URIEncoding
查看>>
【C语言 C++】简单keywordRegister,Const,Static,Volatile,typedef,Define的理解
查看>>
POJ 3518 Prime Gap(素数)
查看>>
[笔记][Java7并发编程实战手冊]3.4 等待多个并发事件的完毕CountDownLatch倒计数闭锁...
查看>>
Java基础(十三):集合
查看>>
c#:使用using关键字自动释放资源未必一定就会有明显好处
查看>>
Python3.6的组件numpy的安装
查看>>
标准SQL语句总结
查看>>
Python的编码问题
查看>>
DirectX怪像之一,我的模型不见了
查看>>
Javascript 打开模式窗口
查看>>
POJ -2513 Colored Sticks 字典树 + 并查集 + 欧拉路
查看>>
【听课笔记】MIT领导力课程笔记:施乐前CEO Anne——在火线上得到的经验
查看>>
【Oracle】手工配置Oracle 10G Enterprise Manager【转载】
查看>>
oracle用户状态
查看>>
[用UpdateLayeredWindow实现任意异形窗口]
查看>>
Android 源码编译make的错误处理
查看>>
【Gson】2.2.4 StackOverflowError 异常
查看>>