对象池的实现

Posted 非法关键字

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对象池的实现相关的知识,希望对你有一定的参考价值。

  • 比较简洁的对象池
技术分享图片
  1 using System;
  2 
  3 namespace ZSLib.ZStudio
  4 {
  5     public sealed class ObjectPool<T> where T : new ()
  6     {
  7         /// <summary>
  8         /// 如果需要可以增加数组的数量
  9         /// </summary>
 10         private int growSize = 20;
 11 
 12         /// <summary>
 13         /// 池对象
 14         /// </summary>
 15         private T[] pool;
 16 
 17         /// <summary>
 18         /// 指向池中元素的索引
 19         /// </summary>
 20         private int nextUnuseIndex = 0;
 21 
 22         public ObjectPool(int size)
 23         {
 24             Resize(size, false);
 25         }
 26 
 27         public ObjectPool(int size, int growSize)
 28         {
 29             this.growSize = growSize;
 30             Resize(size, false);
 31         }
 32 
 33         /// <summary>
 34         /// 池的总大小
 35         /// </summary>
 36         public int Length
 37         {
 38             get { return pool.Length; }
 39         }
 40         
 41         /// <summary>
 42         /// 池中可使用的对象
 43         /// </summary>
 44         public int Available
 45         {
 46             get { return pool.Length - nextUnuseIndex; }
 47         }
 48         
 49         /// <summary>
 50         /// 池中已经分配使用对象的数量
 51         /// </summary>
 52         public int Spawned
 53         {
 54             get { return nextUnuseIndex; }
 55         }
 56 
 57         public T Spawn()
 58         {
 59             T inst = default(T);
 60             
 61             // 如果需要扩大池的大小
 62             if (nextUnuseIndex >= pool.Length)
 63             {
 64                 if (growSize > 0) Resize(pool.Length + growSize, true);
 65                 // 无法扩大池返回default(T)-null
 66                 else return inst;
 67             }
 68 
 69             if (nextUnuseIndex >= 0 && nextUnuseIndex < pool.Length)
 70             {
 71                 inst = pool[nextUnuseIndex];
 72                 nextUnuseIndex++;
 73             }
 74 
 75             return inst;
 76         }
 77         
 78         public void Despawn(T inst)
 79         {
 80             if (nextUnuseIndex > 0)
 81             {
 82                 nextUnuseIndex--;
 83                 pool[nextUnuseIndex] = inst;
 84             }
 85         }
 86         
 87         /// <summary>
 88         /// 快速重建池
 89         /// </summary>
 90         public void Reset()
 91         {
 92             int len = growSize;
 93             if (pool != null) len = pool.Length;
 94             
 95             Resize(len, false);
 96             nextUnuseIndex = 0;
 97         }
 98         
 99         /// <summary>
100         /// 调整池的大小
101         /// </summary>
102         /// <param name="size">新的大小</param>
103         /// <param name="copyExisting">使用原有的元素</param>
104         public void Resize(int size, bool copyExisting)
105         {
106             // 提供多线程支持
107             lock (this)
108             {
109                 int count = 0;
110                 T[] newPool = new T[size];
111                 if (pool != null && copyExisting)
112                 {
113                     count = pool.Length;
114                     Buffer.BlockCopy(pool, 0, newPool, 0, Math.Min(count, size));
115                 }
116 
117                 // 为新增加的对象初始化
118                 for (int i = count; i < size; i++)
119                 {
120                     newPool[i] = new T();
121                 }
122 
123                 pool = newPool;
124             }
125         }
126     }
127 }
View Code
  • 工厂模式的对象池<请参阅考Zenject>
技术分享图片
 1 using System;
 2 namespace Zenject
 3 {
 4     public interface IMemoryPool
 5     {
 6         int NumTotal { get; }
 7         int NumActive { get; }
 8         int NumInactive { get; }
 9 
10         Type ItemType
11         {
12             get;
13         }
14     }
15 
16     public interface IMemoryPool<TValue> : IMemoryPool
17     {
18         TValue Spawn();
19         void Despawn(TValue item);
20     }
21 
22     public interface IMemoryPool<in TParam1, TValue> : IMemoryPool
23     {
24         TValue Spawn(TParam1 param);
25         void Despawn(TValue item);
26     }
27 
28     public interface IMemoryPool<in TParam1, in TParam2, TValue> : IMemoryPool
29     {
30         TValue Spawn(TParam1 param1, TParam2 param2);
31         void Despawn(TValue item);
32     }
33 
34     public interface IMemoryPool<in TParam1, in TParam2, in TParam3, TValue> : IMemoryPool
35     {
36         TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3);
37         void Despawn(TValue item);
38     }
39 
40     public interface IMemoryPool<in TParam1, in TParam2, in TParam3, in TParam4, TValue> : IMemoryPool
41     {
42         TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4);
43         void Despawn(TValue item);
44     }
45 
46     public interface IMemoryPool<in TParam1, in TParam2, in TParam3, in TParam4, in TParam5, TValue> : IMemoryPool
47     {
48         TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5);
49         void Despawn(TValue item);
50     }
51 }
View Code
技术分享图片
  1 using System;
  2 using System.Collections.Generic;
  3 using ModestTree;
  4 
  5 namespace Zenject
  6 {
  7     // Zero parameters
  8     public class MemoryPool<TValue> : MemoryPoolBase<TValue>, IMemoryPool<TValue>
  9     {
 10         public TValue Spawn()
 11         {
 12             var item = GetInternal();
 13             Reinitialize(item);
 14             return item;
 15         }
 16 
 17         protected virtual void Reinitialize(TValue item)
 18         {
 19             // Optional
 20         }
 21     }
 22 
 23     // One parameter
 24     public class MemoryPool<TParam1, TValue>
 25         : MemoryPoolBase<TValue>, IMemoryPool<TParam1, TValue>
 26     {
 27         public TValue Spawn(TParam1 param)
 28         {
 29             var item = GetInternal();
 30             Reinitialize(param, item);
 31             return item;
 32         }
 33 
 34         protected virtual void Reinitialize(TParam1 p1, TValue item)
 35         {
 36             // Optional
 37         }
 38     }
 39 
 40     // Two parameters
 41     public class MemoryPool<TParam1, TParam2, TValue>
 42         : MemoryPoolBase<TValue>, IMemoryPool<TParam1, TParam2, TValue>
 43     {
 44         public TValue Spawn(TParam1 param1, TParam2 param2)
 45         {
 46             var item = GetInternal();
 47             Reinitialize(param1, param2, item);
 48             return item;
 49         }
 50 
 51         protected virtual void Reinitialize(TParam1 p1, TParam2 p2, TValue item)
 52         {
 53             // Optional
 54         }
 55     }
 56 
 57     // Three parameters
 58     public class MemoryPool<TParam1, TParam2, TParam3, TValue>
 59         : MemoryPoolBase<TValue>, IMemoryPool<TParam1, TParam2, TParam3, TValue>
 60     {
 61         public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3)
 62         {
 63             var item = GetInternal();
 64             Reinitialize(param1, param2, param3, item);
 65             return item;
 66         }
 67 
 68         protected virtual void Reinitialize(TParam1 p1, TParam2 p2, TParam3 p3, TValue item)
 69         {
 70             // Optional
 71         }
 72     }
 73 
 74     // Four parameters
 75     public class MemoryPool<TParam1, TParam2, TParam3, TParam4, TValue>
 76         : MemoryPoolBase<TValue>, IMemoryPool<TParam1, TParam2, TParam3, TParam4, TValue>
 77     {
 78         public TValue Spawn(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4)
 79         {
 80             var item = GetInternal();
 81             Reinitialize(param1, param2, param3, param4, item);
 82             return item;
 83         }
 84 
 85         protected virtual void Reinitialize(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4, TValue item)
 86         {
 87             // Optional
 88         }
 89     }
 90 
 91     // Five parameters
 92     public class MemoryPool<TParam1, TParam2, TParam3, TParam4, TParam5, TValue>
 93         : MemoryPoolBase<TValue>, IMemoryPool<TParam1, TParam2, TParam3, TParam4, TParam5, TValue>
 94     {
 95         public TValue Spawn(
 96             TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5)
 97         {
 98             var item = GetInternal();
 99             Reinitialize(param1, param2, param3, param4, param5, item);
100             return item;
101         }
102 
103         protected virtual void Reinitialize(TParam1 p1, TParam2 p2, TParam3 p3, TParam4 p4, TParam5 p5, TValue item)
104         {
105             // Optional
106         }
107     }
108 }
View Code
技术分享图片
 1 public class Foo
 2 {
 3     public class Pool : MemoryPool<Foo>
 4     {
 5     }
 6 }
 7 
 8 public class Bar
 9 {
10     readonly Foo.Pool _fooPool;
11     readonly List<Foo> _foos = new List<Foo>();
12 
13     public Bar(Foo.Pool fooPool)
14     {
15         _fooPool = fooPool;
16     }
17 
18     public void AddFoo()
19     {
20         _foos.Add(_fooPool.Spawn());
21     }
22 
23     public void RemoveFoo()
24     {
25         var foo = _foos[0];
26         _fooPool.Despawn(foo);
27         _foos.Remove(foo);
28     }
29 }
30 
31 public class TestInstaller : MonoInstaller<TestInstaller>
32 {
33     public override void InstallBindings()
34     {
35         Container.Bind<Bar>().AsSingle();
36         Container.BindMemoryPool<Foo, Foo.Pool>();
37     }
38 }
View Code

当然也是可以抛开D/I框架来使用的.

以上是关于对象池的实现的主要内容,如果未能解决你的问题,请参考以下文章

对象池的简单实现

c++11 对象池的实现

Unity对象池的实现

对象池的实现

揭秘池化技术--内存池的实现

Linux下简单线程池的实现