对象池的设计

ObjectPool 








//从池中获取对象

T borrowObject() throws Exception, NoSuchElementException,IllegalStateException;

//将对象放回池中

void returnObject(T obj) throws Exception;

//废弃对象

void invalidateObject(T obj) throws Exception;

//添加对象

void addObject() throws Exception, IllegalStateException,UnsupportedOperationException;

//获取对象个数

int getNumIdle();

//获取活跃对象个数

int getNumActive();

//清除池,池可用

void clear() throws Exception, UnsupportedOperationException;

//关闭池,池不可用

void close(); 


PooledObjectFactory








//创建一个新对象;当对象池中的对象个数不足时,将会使用此方法来"输出"一个新的"对象",并交付给对象池管理

PooledObject<T> makeObject() throws Exception;

//销毁对象,如果对象池中检测到某个"对象"idle的时间超时,或者操作者向对象池"归还对象"时检测到"对象"已经无效,那么此时将会导致"对象销毁";"销毁对象"的操作设计相差甚远,但是必须明确:当调用此方法时,"对象"的生命周期必须结束.如果object是线程,那么此时线程必须退出;如果object是socket操作,那么此时socket必须关闭;如果object是文件流操作,那么此时"数据flush"且正常关闭.

void destroyObject(PooledObject<T> p) throws Exception;

//检测对象是否"有效";Pool中不能保存无效的"对象",因此"后台检测线程"会周期性的检测Pool中"对象"的有效性,如果对象无效则会导致此对象从Pool中移除,并destroy;此外在调用者从Pool获取一个"对象"时,也会检测"对象"的有效性,确保不能讲"无效"的对象输出给调用者;当调用者使用完毕将"对象归还"到Pool时,仍然会检测对象的有效性.所谓有效性,就是此"对象"的状态是否符合预期,是否可以对调用者直接使用;如果对象是Socket,那么它的有效性就是socket的通道是否畅通/阻塞是否超时等.

boolean validateObject(PooledObject<T> p);

// "激活"对象,当Pool中决定移除一个对象交付给调用者时额外的"激活"操作,比如可以在activateObject方法中"重置"参数列表让调用者使用时感觉像一个"新创建"的对象一样;如果object是一个线程,可以在"激活"操作中重置"线程中断标记",或者让线程从阻塞中唤醒等;如果object是一个socket,那么可以在"激活操作"中刷新通道,或者对socket进行链接重建(假如socket意外关闭)等.

void activateObject(PooledObject<T> p) throws Exception;

//"钝化"对象,当调用者"归还对象"时,Pool将会"钝化对象";钝化的言外之意,就是此"对象"暂且需要"休息"一下.如果object是一个socket,那么可以passivateObject中清除buffer,将socket阻塞;如果object是一个线程,可以在"钝化"操作中将线程sleep或者将线程中的某个对象wait.需要注意的时,activateObject和passivateObject两个方法需要对应,避免死锁或者"对象"状态的混乱.

void passivateObject(PooledObject<T> p) throws Exception; 


PooledObject








T getObject();

long getCreateTime();

long getActiveTimeMillis();

long getIdleTimeMillis();

long getLastBorrowTime();

long getLastReturnTime();

long getLastUsedTime();

int compareTo(PooledObject<T> other);

boolean equals(Object obj);

int hashCode();

String toString();

//后台清理线程

boolean startEvictionTest();

boolean endEvictionTest(Deque<PooledObject<T>> idleQueue);

boolean allocate();

boolean deallocate();

void invalidate()

void setLogAbandoned(boolean logAbandoned);

void use();

void printStackTrace(PrintWriter writer);

PooledObjectState getState();

//自动补偿功能

void markAbandoned();

void markReturning(); 

    commons pool2 对象池类型

  

SoftReferenceObjectPool








//可用对象列表

private final LinkedBlockingDeque<PooledSoftReference<T>> idleReferences = new LinkedBlockingDeque<PooledSoftReference<T>>();

//所有对象列表

private final ArrayList<PooledSoftReference<T>> allReferences = new ArrayList<PooledSoftReference<T>>(); 


borrowObject








//可用对象列表

private final LinkedBlockingDeque<PooledSoftReference<T>> idleReferences = new LinkedBlockingDeque<PooledSoftReference<T>>();

//所有对象列表

private final ArrayList<PooledSoftReference<T>> allReferences = new ArrayList<PooledSoftReference<T>>();

 

 

    public synchronized T borrowObject() throws Exception {

        assertOpen();//确定池打开

        T obj = null;

        boolean newlyCreated = false;

        PooledSoftReference<T> ref = null;

        while (null == obj) {

            if (idleReferences.isEmpty()) {

                if (null == factory) {

                    throw new NoSuchElementException();

                } else {

                    //如果可用列表为空则创建新的对象

                    newlyCreated = true;

                    obj = factory.makeObject().getObject();

                    //累加计数器

                    createCount++;

                    // Do not register with the queue

                    //关联

                    ref = new PooledSoftReference<T>(new SoftReference<T>(obj));

                    //添加进所有列表

                    allReferences.add(ref);

                }

            } else {

                //从可用队列获取对象

                ref = idleReferences.pollFirst();

                obj = ref.getObject();

                // Clear the reference so it will not be queued, but replace with a

                // a new, non-registered reference so we can still track this object

                // in allReferences

                //重建关联

                ref.getReference().clear();

                ref.setReference(new SoftReference<T>(obj));

            }

            if (null != factory && null != obj) {

                try {

                    //激活对象

                    factory.activateObject(ref);

                    if (!factory.validateObject(ref)) {

                        throw new Exception("ValidateObject failed");

                    }

                } catch (Throwable t) {

                    PoolUtils.checkRethrow(t);

                    try {

                        destroy(ref);

                    } catch (Throwable t2) {

                        PoolUtils.checkRethrow(t2);

                        // Swallowed

                    } finally {

                        obj = null;

                    }

                    if (newlyCreated) {

                        throw new NoSuchElementException(

                                "Could not create a validated object, cause: " +

                                        t.getMessage());

                    }

                }

            }

        }

         

        numActive++;

        //锁定

        ref.allocate();

        return obj;

    } 


returnObject








public synchronized void returnObject(T obj) throws Exception {

    boolean success = !isClosed();

    //判断对象来自于池【通过对象的equals方法】

    final PooledSoftReference<T> ref = findReference(obj);

    if (ref == null) {

        throw new IllegalStateException(

            "Returned object not currently part of this pool");

    }

    if (factory != null) {

        //判断对象合格

        if (!factory.validateObject(ref)) {

            success = false;

        } else {

            try {

                //钝化对象

                factory.passivateObject(ref);

            } catch (Exception e) {

                success = false;

            }

        }

    }

     

    boolean shouldDestroy = !success;

    numActive--;

    if (success) {

        //如果对象合格并且钝化成功则解除锁定并添加到可用列表中

        // Deallocate and add to the idle instance pool

        ref.deallocate();

        idleReferences.add(ref);

    }

    notifyAll(); // numActive has changed

 

    if (shouldDestroy && factory != null) {

        try {

            destroy(ref);

        } catch (Exception e) {

            // ignored

        }

    }

} 


弱引用对象池最简单,没有后台清理线程只有当内存不够的情况下由虚拟机清除。

GenericObjectPool








//默认出队方式

private volatile boolean lifo = BaseObjectPoolConfig.DEFAULT_LIFO; 

//后台清理逻辑

class Evictor extends TimerTask

//所有对象列表

private final Map<T, PooledObject<T>> allObjects = new ConcurrentHashMap<T, PooledObject<T>>();

//可用对象列表【双向链表】

private final LinkedBlockingDeque<PooledObject<T>> idleObjects = new LinkedBlockingDeque<PooledObject<T>>(); 


borrowObject








    public T borrowObject(long borrowMaxWaitMillis) throws Exception {

        assertOpen();

//是否在获取对象的时候检查对象,开启的话则检查【主要是检查过期】

        AbandonedConfig ac = this.abandonedConfig;

        if (ac != null && ac.getRemoveAbandonedOnBorrow() &&

                (getNumIdle() < 2) &&

                (getNumActive() > getMaxTotal() - 3) ) {

            removeAbandoned(ac);

        }

 

        PooledObject<T> p = null;

 

        // Get local copy of current config so it is consistent for entire

        // method execution

//当池耗尽的时候是否block,如果block的话则会idleObjects.pollFirst(borrowMaxWaitMillis,TimeUnit.MILLISECONDS);否则直接throw new NoSuchElementException("Pool exhausted");

        boolean blockWhenExhausted = getBlockWhenExhausted();

 

        boolean create;

        long waitTime = 0;

 

        while (p == null) {

            create = false;

            if (blockWhenExhausted) {

                p = idleObjects.pollFirst();

                if (p == null) {

                    create = true;

                    p = create();

                }

                if (p == null) {

                    if (borrowMaxWaitMillis < 0) {

                        p = idleObjects.takeFirst();

                    } else {

                        waitTime = System.currentTimeMillis();

                        p = idleObjects.pollFirst(borrowMaxWaitMillis,

                                TimeUnit.MILLISECONDS);

                        waitTime = System.currentTimeMillis() - waitTime;

                    }

                }

                if (p == null) {

                    throw new NoSuchElementException(

                            "Timeout waiting for idle object");

                }

                if (!p.allocate()) {

                    p = null;

                }

            } else {

                p = idleObjects.pollFirst();

                if (p == null) {

                    create = true;

                    p = create();

                }

                if (p == null) {

                    throw new NoSuchElementException("Pool exhausted");

                }

                if (!p.allocate()) {

                    p = null;

                }

            }

 

            if (p != null) {

                try {

//激活对象

                    factory.activateObject(p);

                } catch (Exception e) {

                    try {

                        destroy(p);

                    } catch (Exception e1) {

                        // Ignore - activation failure is more important

                    }

                    p = null;

                    if (create) {

                        NoSuchElementException nsee = new NoSuchElementException(

                                "Unable to activate object");

                        nsee.initCause(e);

                        throw nsee;

                    }

                }

//如果获取对象是检查则validateObject

                if (p != null && getTestOnBorrow()) {

                    boolean validate = false;

                    Throwable validationThrowable = null;

                    try {

                        validate = factory.validateObject(p);

                    } catch (Throwable t) {

                        PoolUtils.checkRethrow(t);

                        validationThrowable = t;

                    }

//检查不通过则destroy

                    if (!validate) {

                        try {

                            destroy(p);

                            destroyedByBorrowValidationCount.incrementAndGet();

                        } catch (Exception e) {

                            // Ignore - validation failure is more important

                        }

                        p = null;

                        if (create) {

                            NoSuchElementException nsee = new NoSuchElementException(

                                    "Unable to validate object");

                            nsee.initCause(validationThrowable);

                            throw nsee;

                        }

                    }

                }

            }

        }

 

        updateStatsBorrow(p, waitTime);

 

        return p.getObject();

    } 


returnObject








    public void returnObject(T obj) {

        PooledObject<T> p = allObjects.get(obj);

 

        if (!isAbandonedConfig()) {

            if (p == null) {

                throw new IllegalStateException(

                        "Returned object not currently part of this pool");

            }

        } else {

            if (p == null) {

                return;  // Object was abandoned and removed

            } else {

                // Make sure object is not being reclaimed

                synchronized(p) {

                    final PooledObjectState state = p.getState();

                    if (state == PooledObjectState.ABANDONED ||

                            state == PooledObjectState.INVALID) {

                        return;

                    } else {

                        p.markReturning(); // Keep from being marked abandoned

                    }

                }

            }

        }

 

        long activeTime = p.getActiveTimeMillis();

//验证合格

        if (getTestOnReturn()) {

            if (!factory.validateObject(p)) {

                try {

                    destroy(p);

                } catch (Exception e) {

                    swallowException(e);

                }

                updateStatsReturn(activeTime);

                return;

            }

        }

//钝化

        try {

            factory.passivateObject(p);

        } catch (Exception e1) {

            swallowException(e1);

            try {

                destroy(p);

            } catch (Exception e) {

                swallowException(e);

            }

            updateStatsReturn(activeTime);

            return;

        }

 

        if (!p.deallocate()) {

            throw new IllegalStateException(

                    "Object has already been retured to this pool or is invalid");

        }

//池大小

        int maxIdleSave = getMaxIdle();

        if (isClosed() || maxIdleSave > -1 && maxIdleSave <= idleObjects.size()) {

            try {

                destroy(p);

            } catch (Exception e) {

                swallowException(e);

            }

        } else {

            if (getLifo()) {

                idleObjects.addFirst(p);

            } else {

                idleObjects.addLast(p);

            }

        }

        updateStatsReturn(activeTime);

    } 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值