对象池

作者: 升空的焰火 | 来源:发表于2018-11-15 15:43 被阅读0次

一、对象池概述:

对于那些实例化开销比较大,并且生命周期比较短的对象,我们可以通过池就行管理。所谓池,就相当于一个仓库,里面的东西是有借有还的。这样可以控制池内对象的数量,开销,并且一个对象实例可以重复使用。

二、自定义连接池:

1.一个连接池对象,它应该具备一个繁忙状态,并且我拥有获取这个对象,判断繁忙状态,设置繁忙状态的api.

package com.example.springboot1.objectPool;

public  class PoolObject {

private T objection =null;// 外界使用的对象

    private boolean busy =false; // 此对象是否正在使用的标志,默认没有正在使用

    // 构造函数,池化对象

    public PoolObject(T objection) {

this.objection = objection;

    }

// 返回此对象中的对象

    public T getObject() {

return objection;

    }

// 设置此对象的,对象

    public void setObject(T objection) {

this.objection = objection;

    }

// 获得对象对象是否忙

    public boolean isBusy() {

return busy;

    }

// 设置对象的对象正在忙

    public void setBusy(boolean busy) {

this.busy = busy;

    }

}

2.对象池,一个对象池,它需要一些基本配置熟悉,如最大连接数,空闲数,超时时间等等,并且需要创建池,关系池,创建对象,归还对象,获取空闲对象,统计等相关api。

package com.example.springboot1.objectPool;

import com.example.springboot1.objectPool.PoolObject;

import java.util.Enumeration;

import java.util.Vector;

public abstract class ObjectPool {

public static int numObjects =10; // 对象池的大小

    public static int maxObjects =50; // 对象池最大的大小

    protected Vector>objects =null; // 存放对象池中对象的向量(PooledObject类型)

    public ObjectPool() {

}

/*** 创建一个对象池 ***/

    public synchronized void createPool() {

// 确保对象池没有创建。如果创建了,保存对象的向量 objects 不会为空

        if (objects !=null) {

return; // 如果己经创建,则返回

        }

// 创建保存对象的向量 , 初始时有 0 个元素

        objects =new Vector>();

        for (int i =0; i

objects.addElement(create());

        }

}

public abstract PoolObjectcreate();

    public synchronized T getObject() {

// 确保对象池己被创建

        if (objects ==null) {

return null; // 对象池还没创建,则返回null

        }

T t = getFreeObject(); // 获得一个可用的对象

        // 如果目前没有可以使用的对象,即所有的对象都在使用中

        while (t ==null) {

wait(250);

            t = getFreeObject(); // 重新再试,直到获得可用的对象,如果

            // getFreeObject() 返回的为 null,则表明创建一批对象后也不可获得可用对象

        }

return t;// 返回获得的可用的对象

    }

/**

    * 本函数从对象池对象 objects 中返回一个可用的的对象,如果 当前没有可用的对象,则创建几个对象,并放入对象池中。

    * 如果创建后,所有的对象都在使用中,则返回 null

*/

    private T getFreeObject() {

// 从对象池中获得一个可用的对象

        T obj = findFreeObject();

        if (obj ==null) {

createObjects(10); // 如果目前对象池中没有可用的对象,创建一些对象

            // 重新从池中查找是否有可用对象

            obj = findFreeObject();

            // 如果创建对象后仍获得不到可用的对象,则返回null

            if (obj ==null) {

return null;

            }

}

return obj;

    }

public void createObjects(int increment){

for (int i =0; i < increment; i++) {

if (objects.size() >maxObjects) {

return;

            }

objects.addElement(create());

        }

}

/**

    * 查找对象池中所有的对象,查找一个可用的对象, 如果没有可用的对象,返回 null

*/

    private T findFreeObject() {

T obj =null;

        PoolObject pObj =null;

        // 获得对象池向量中所有的对象

        Enumeration> enumerate =objects.elements();

        // 遍历所有的对象,看是否有可用的对象

        while (enumerate.hasMoreElements()) {

pObj = (PoolObject) enumerate.nextElement();

            // 如果此对象不忙,则获得它的对象并把它设为忙

            if (!pObj.isBusy()) {

obj = pObj.getObject();

                pObj.setBusy(true);

            }

}

return obj;// 返回找到到的可用对象

    }

/**

    * 此函数返回一个对象到对象池中,并把此对象置为空闲。 所有使用对象池获得的对象均应在不使用此对象时返回它。

    */

    public void returnObject(T obj) {

// 确保对象池存在,如果对象没有创建(不存在),直接返回

        if (objects ==null) {

return;

        }

PoolObject pObj =null;

        Enumeration> enumerate =objects.elements();

        // 遍历对象池中的所有对象,找到这个要返回的对象对象

        while (enumerate.hasMoreElements()) {

pObj = (PoolObject) enumerate.nextElement();

            // 先找到对象池中的要返回的对象对象

            if (obj == pObj.getObject()) {

// 找到了 , 设置此对象为空闲状态

                pObj.setBusy(false);

break;

            }

}

}

/**

    * 关闭对象池中所有的对象,并清空对象池。

    */

    public synchronized void closeObjectPool() {

// 确保对象池存在,如果不存在,返回

        if (objects ==null) {

return;

        }

PoolObject pObj =null;

        Enumeration> enumerate =objects.elements();

        while (enumerate.hasMoreElements()) {

pObj = (PoolObject) enumerate.nextElement();

            // 如果忙,等 0.5 秒

            if (pObj.isBusy()) {

wait(500); // 等

            }

// 从对象池向量中删除它

            objects.removeElement(pObj);

        }

// 置对象池为空

        objects =null;

    }

/**

    * 使程序等待给定的毫秒数

    */

    private void wait(int mSeconds) {

try {

Thread.sleep(mSeconds);

        }catch (InterruptedException e) {

}

}

}

3.开源的池工具,apach commons-pool

继承BasePooledObjectFactory或者PooledObjectFactory,实现makeObject方法。

public class IntellifObjectPoolFactory implements PooledObjectFactory {

private ClasstClass;

    private T obj;

    @Override

    public PooledObjectwrap(T t) {

return null;

    }

@Override

    public PooledObjectmakeObject()throws Exception {

return new DefaultPooledObject(this.obj);

    }

@Override

    public void destroyObject(PooledObject pooledObject)

throws Exception {

}

@Override

    public boolean validateObject(PooledObject pooledObject) {

//默认是false,代表验证不通过,这里随机好了

        return new Random().nextInt()%2==0;

    }

@Override

    public void activateObject(PooledObject pooledObject)

throws Exception {

}

@Override

    public void passivateObject(PooledObject pooledObject)

throws Exception {

}

}

创建代理池对象IntellifObjectPool

public class IntellifObjectPool {

private static ConcurrentHashMappoolSet =new ConcurrentHashMap<>();

    private StringpoolName;

    private int maxTotal;

    private GenericObjectPoolgenericObjectPool;

    private ClasstClass;

    private T obj;

    public IntellifObjectPool(String poolName,Integer maxTotal,T obj)throws ClassNotFoundException {

if(IntellifObjectPool.poolSet.get(poolName)!=null){

this.genericObjectPool =poolSet.get(poolName);

        }else {

GenericObjectPoolConfig conf =new GenericObjectPoolConfig();

            conf.setMaxTotal(maxTotal);

            conf.setTestOnBorrow(false);

            conf.setTestOnReturn(true);

            conf.setTestWhileIdle(true);

            conf.setMaxIdle(maxTotal);

            conf.setMaxWaitMillis(300);

            this.maxTotal = maxTotal;

            this.genericObjectPool =new GenericObjectPool(new IntellifObjectPoolFactory(tClass), conf);

        }

}

public StringgetPoolName() {

return poolName;

    }

public void setPoolName(String poolName) {

this.poolName = poolName;

    }

public int getMaxTotal() {

return maxTotal;

    }

public void setMaxTotal(int maxTotal) {

this.maxTotal = maxTotal;

    }

public GenericObjectPoolgetGenericObjectPool() {

return genericObjectPool;

    }

public void setGenericObjectPool(GenericObjectPool genericObjectPool) {

this.genericObjectPool = genericObjectPool;

    }

public ClassgettClass() {

return tClass;

    }

public void settClass(Class tClass) {

this.tClass = tClass;

    }

}

ObjectPool

//从池中获取对象T borrowObject();

//将对象放回池中void returnObject(T obj)

//废弃对象void invalidateObject(T obj)

//添加对象void addObject();

//获取空闲对象个数 int getNumIdle();

//获取活跃对象个数int getNumActive();

//清除池,池可用void clear()

//关闭池,池不可用void close();

通过代理类获取池对象,进行池的对象取用与归还。目前需要手动从池中取数据,再归还,再关闭池。

4.扩展想法

1.实现池对象的自动归还

2.泛型的扩展,实例的复制,活性化对象池。

相关文章

  • Unity 类对象池资源池对象池

    类对象池 包含创建对象池,取对象池中的内容,回收。 对象管理类 因为使用加载AB包的时候可能会频繁创建类,但是ne...

  • Laya_2D示例项目使用对象池预制体的创建、位置设置和添加到父

    //使用对象池创建盒子 1.对象池的使用 对象池创建箱子 let box = Laya.Pool.getI...

  • Unity--简单的对象池

    简单的对象池分三步走: 建立对象池 拿到对象 回收对象 Test为对象池,Obj为自动回收的物体 Test.cs ...

  • 对象池

    一、对象池概述: 对于那些实例化开销比较大,并且生命周期比较短的对象,我们可以通过池就行管理。所谓池,就相当于一个...

  • 对象池

  • 对象池

    概要 看到现在,Netty之设计精妙,令人感叹。优化至极,令人发指。在高并发场景下,对象的分配的损耗是很大的,特别...

  • 对象池

    讲在前面 为什么要有对象池?我们需要一种类型的实例时候往往回去new一个这样会造成gc问题对象池根本奥义就在于一个...

  • 对象池

    UGUI 中使用的对象池 在 C:\Files\Unity\Projects\UGUITest\PackageSo...

  • 对象池

    java对象池化技术https://blog.csdn.net/tiane5hao/article/details...

  • 对象池

    using UnityEngine;using System.Collections.Generic; publi...

网友评论

      本文标题:对象池

      本文链接:https://www.haomeiwen.com/subject/fvsefqtx.html