pool(四)——EvictionTimer

 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: `multiprocessing.pool.Pool` 是 Python 的多进程编程库 `multiprocessing` 中的一个类,用于简化多进程编程的过程。该类提供了一个简单的方法来并行地执行多个任务,它可以通过多个进程(通常是 CPU 核心数量)同时处理任务,从而提高程序的执行效率。 ### 回答2: multiprocessing.pool.Pool是Python中的一个模块,它提供了一种简单的方式来并行执行多个进程。 Pool类可以用于创建一个进程池,这个进程池可以管理多个工作进程,从而实现并行计算。通过将任务分配给进程池中的多个进程来同时执行,可以显著提高程序的执行效率。 当我们需要对某个函数进行大量重复计算或者需要进行大规模的数据处理时,使用Pool类可以将这些任务分配给多个进程来同时执行,从而节省时间。 Pool类的主要方法有map()和apply_async()。map()方法可以将一个可迭代对象中的元素按照指定的函数进行计算,并返回计算结果的列表。apply_async()方法可以异步地传递单个任务给进程池中的一个进程,并返回一个AsyncResult对象。 使用Pool类时,可以通过设置进程池的大小来控制并行执行的进程数量。一般来说,进程池的大小应该根据计算机的CPU核心数来确定,以达到最佳的计算效果。 需要注意的是,在使用Pool类时,要确保被传递给进程池中的函数是可以独立执行的,即不依赖于其他全局变量或状态。此外,如果需要使用共享状态或共享内存,可以使用multiprocessing模块中的其他类和方法。 总之,multiprocessing.pool.Pool是Python中用于并行计算的一个强大工具,能够有效地提高程序的执行效率。通过将多个任务分配给进程池中的多个进程来同时执行,可以充分利用计算机资源,减少计算时间,提高工作效率。 ### 回答3: multiprocessing.pool.Pool是Python标准库中的一个类,用于实现进程池的功能。进程池是一种并发执行任务的方式,它通过预先创建一定数量的子进程,并维护一个任务队列来实现任务的并发执行。 创建一个进程池可以通过Pool类的构造方法来完成,参数通常包括进程池的大小、初始化函数等。进程池创建后,可以使用其提供的方法来向任务队列中添加任务,并且进程池会自动安排空闲的子进程来执行任务。任务的执行结果可以通过返回值或回调函数来获取。 进程池的好处是可以充分利用多核CPU的性能,提高程序的执行效率。同时,进程池的使用也可以简化任务的管理和调度,使得代码更加简洁易懂。 然而,进程池也有一些要注意的地方。首先,进程池在创建时需要占用一定的系统资源,特别是如果进程池的大小设置过大,可能会导致系统负载过高。其次,进程池中的任务是并发执行的,因此需要注意线程安全的问题,如共享资源的同步与互斥。 总结来说,multiprocessing.pool.Pool是一个方便实现进程池的工具类,可以用于提高并发执行任务的效率。仔细使用该类可以充分发挥多核CPU的潜力,但也需要注意资源占用和线程安全的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值