zoukankan      html  css  js  c++  java
  • 对象池 object pool

    对象池适用于:

    • 对象的创建很耗时
    • 对象频繁地释放再创建

    对象池的实现:将释放的对象放进对象池中,在新建对象时,从对象池取对象

    public class ObjectPool<T> where T : class, new()
    {
        private Stack<T> m_objectStack = new Stack<T>();
    
        public T New()
        {
            return (m_objectStack.Count == 0) ? new T() : m_objectStack.Pop();
        }
    
        public void Store(T t)
        {
            m_objectStack.Push(t);
        }
    }

    改进第一步:对象被重新使用前,reset所有的成员变量。

    public class ObjectPool<T> where T : class, new()
    {
        private Stack<T> m_objectStack;
    
        private Action<T> m_resetAction; //indicate whether need reset
        private Action<T> m_onetimeInitAction; //indicate whether need initialize
    
        public ObjectPool(int initialBufferSize, Action<T>
            ResetAction = null, Action<T> OnetimeInitAction = null)
        {
            m_objectStack = new Stack<T>(initialBufferSize);
            m_resetAction = ResetAction;
            m_onetimeInitAction = OnetimeInitAction;
        }
    
        public T New()
        {
            if (m_objectStack.Count > 0)
            {
                T t = m_objectStack.Pop();
    
                if (m_resetAction != null)
                    m_resetAction(t);
    
                return t;
            }
            else
            {
                T t = new T();
    
                if (m_onetimeInitAction != null)
                    m_onetimeInitAction(t);
    
                return t;
            }
        }
    
        public void Store(T obj)
        {
            m_objectStack.Push(obj);
        }
    }

    参数T被指明为”where T:class,new()”,意味着有两个限制。首先,T必须为一个类(毕竟,只有引用类型需要被obejct-pool);其次,它必须要有一个无参构造函数。

    以下是池的使用方法:

    class SomeClass : MonoBehaviour
    {
        private ObjectPool<List<Vector3>> m_poolOfListOfVector3 =
            //32为假设的最大数量
            new ObjectPool<List<Vector3>>(32,
            (list) => {
                list.Clear();
            },
            (list) => {
                //初始化容量为1024
                list.Capacity = 1024;
            });
    
        void Update()
        {
            List<Vector3> listVector3 = m_poolOfListOfVector3.New();
    
            // do stuff
    
            m_poolOfListOfVector3.Store(listVector3);
        }
    }

    改进第二步:允许一次性回收所有已经池化的对象

    public class ObjectPoolWithCollectiveReset<T> where T : class, new()
    {
        private List<T> m_objectList; //Stack<T>被List<T>代替,可以跟踪最近创建或释放的对象在list中索引
        private int m_nextAvailableIndex = 0;
    
        private Action<T> m_resetAction;
        private Action<T> m_onetimeInitAction;
    
        public ObjectPoolWithCollectiveReset(int initialBufferSize, Action<T>
            ResetAction = null, Action<T> OnetimeInitAction = null)
        {
            m_objectList = new List<T>(initialBufferSize);
            m_resetAction = ResetAction;
            m_onetimeInitAction = OnetimeInitAction;
        }
    
        public T New()
        {
            if (m_nextAvailableIndex < m_objectList.Count)
            {
                // an allocated object is already available; just reset it
                T t = m_objectList[m_nextAvailableIndex];
                m_nextAvailableIndex++;
    
                if (m_resetAction != null)
                    m_resetAction(t);
    
                return t;
            }
            else
            {
                // no allocated object is available
                T t = new T();
                m_objectList.Add(t);
                m_nextAvailableIndex++;
    
                if (m_onetimeInitAction != null)
                    m_onetimeInitAction(t);
    
                return t;
            }
        }
    
        public void ResetAll() //原本的store()
        {
           //重置索引
            m_nextAvailableIndex = 0;
        }
    }

    局限:显然,当我们需要一个其它类型的对象池时就需要重新申明一个。或许我们可以实现一个对用户透明。创建管理所有类型池的ObjectPool。

  • 相关阅读:
    (转载)Rime输入法—鼠须管(Squirrel)词库添加及配置
    (转载)Windows下小狼毫输入法(Rime)的安装与配置(含导入搜狗词库)
    (转载)WinCC 卸载后 Simatic Shell 的删除
    (转载)西门子PLC学习笔记十五-(数据块及数据访问方式)
    (转载)一张表搞清楚西门子S7系列标准DB块与优化DB块
    (转载)Navicat Premium 12.1.16.0安装与激活
    (转载)MySQl数据库-批量添加数据的两种方法
    (转载)用C#实现MySQL建库及建表
    设置MYSQL数据库编码为UTF-8
    [设计模式]工厂方法模式(Factory Method)
  • 原文地址:https://www.cnblogs.com/qionglouyuyu/p/5015166.html
Copyright © 2011-2022 走看看