设计模式之美:Object Pool(对象池)

索引

意图

运用对象池化技术可以显著地提升性能,尤其是当对象的初始化过程代价较大或者频率较高时。

Object pooling can offer a significant performance boost; it is most effective in situations where the cost of initializing a class instance is high, the rate of instantiation of a class is high.

结构

设计模式之美:Object Pool(对象池)

参与者

Reusable

  • 类的实例与其他对象进行有限时间的交互。

ReusablePool

  • 管理类的实例。

Client

  • 使用类的实例。

适用性

当以下情况成立时可以使用 Object Pool 模式:

  • 类的实例可重用于交互。
  • 类的实例化过程开销较大。
  • 类的实例化的频率较高。
  • 类参与交互的时间周期有限。

效果

  • 节省了创建类的实例的开销。
  • 节省了创建类的实例的时间。
  • 存储空间随着对象的增多而增大。

相关模式

  • 通常,可以使用 Singleton 模式实现 ReusablePool 类。
  • Factory Method 模式封装了对象的创建的过程,但其不负责管理对象。Object Pool 负责管理对象。

实现

实现方式(一):实现 DatabaseConnectionPool 类。

如果 Client 调用 ObjectPool 的 AcquireReusable() 方法来获取 Reusable 对象,当在 ObjectPool 中存在可用的 Reusable 对象时,其将一个 Reusable 从池中移除,然后返回该对象。如果池为空,则 ObjectPool 会创建一个新的 Reusable 对象。

 namespace ObjectPoolPattern.Implementation1
{
public abstract class ObjectPool<T>
{
private TimeSpan _expirationTime;
private Dictionary<T, DateTime> _unlocked;
private Dictionary<T, DateTime> _locked;
private readonly object _sync = new object(); public ObjectPool()
{
_expirationTime = TimeSpan.FromSeconds();
_locked = new Dictionary<T, DateTime>();
_unlocked = new Dictionary<T, DateTime>();
} public ObjectPool(TimeSpan expirationTime)
: this()
{
_expirationTime = expirationTime;
} protected abstract T Create(); public abstract bool Validate(T reusable); public abstract void Expire(T reusable); public T CheckOut()
{
lock (_sync)
{
T reusable = default(T); if (_unlocked.Count > )
{
foreach (var item in _unlocked)
{
if ((DateTime.UtcNow - item.Value) > _expirationTime)
{
// object has expired
_unlocked.Remove(item.Key);
Expire(item.Key);
}
else
{
if (Validate(item.Key))
{
// find a reusable object
_unlocked.Remove(item.Key);
_locked.Add(item.Key, DateTime.UtcNow);
reusable = item.Key;
break;
}
else
{
// object failed validation
_unlocked.Remove(item.Key);
Expire(item.Key);
}
}
}
} // no object available, create a new one
if (reusable == null)
{
reusable = Create();
_locked.Add(reusable, DateTime.UtcNow);
} return reusable;
}
} public void CheckIn(T reusable)
{
lock (_sync)
{
_locked.Remove(reusable);
_unlocked.Add(reusable, DateTime.UtcNow);
}
}
} public class DatabaseConnection : IDisposable
{
// do some heavy works
public DatabaseConnection(string connectionString)
{
} public bool IsOpen { get; set; } // release something
public void Dispose()
{
}
} public class DatabaseConnectionPool : ObjectPool<DatabaseConnection>
{
private string _connectionString; public DatabaseConnectionPool(string connectionString)
: base(TimeSpan.FromMinutes())
{
this._connectionString = connectionString;
} protected override DatabaseConnection Create()
{
return new DatabaseConnection(_connectionString);
} public override void Expire(DatabaseConnection connection)
{
connection.Dispose();
} public override bool Validate(DatabaseConnection connection)
{
return connection.IsOpen;
}
} public class Client
{
public static void TestCase1()
{
// Create the ConnectionPool:
DatabaseConnectionPool pool = new DatabaseConnectionPool(
"Data Source=DENNIS;Initial Catalog=TESTDB;Integrated Security=True;"); // Get a connection:
DatabaseConnection connection = pool.CheckOut(); // Use the connection // Return the connection:
pool.CheckIn(connection);
}
}
}

实现方式(二):使用对象构造方法和预分配方式实现 ObjectPool 类。

 namespace ObjectPoolPattern.Implementation2
{
/// <summary>
/// 对象池
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
public class ObjectPool<T> where T : class
{
private readonly Func<T> _objectFactory;
private readonly ConcurrentQueue<T> _queue = new ConcurrentQueue<T>(); /// <summary>
/// 对象池
/// </summary>
/// <param name="objectFactory">构造缓存对象的函数</param>
public ObjectPool(Func<T> objectFactory)
{
_objectFactory = objectFactory;
} /// <summary>
/// 构造指定数量的对象
/// </summary>
/// <param name="count">数量</param>
public void Allocate(int count)
{
for (int i = ; i < count; i++)
_queue.Enqueue(_objectFactory());
} /// <summary>
/// 缓存一个对象
/// </summary>
/// <param name="obj">对象</param>
public void Enqueue(T obj)
{
_queue.Enqueue(obj);
} /// <summary>
/// 获取一个对象
/// </summary>
/// <returns>对象</returns>
public T Dequeue()
{
T obj;
return !_queue.TryDequeue(out obj) ? _objectFactory() : obj;
}
} class Program
{
static void Main(string[] args)
{
var pool = new ObjectPool<byte[]>(() => new byte[]);
pool.Allocate(); var buffer = pool.Dequeue(); // .. do something here .. pool.Enqueue(buffer);
}
}
}

设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

上一篇:js格式化日期 年月日


下一篇:Dynamic Property Wizard 添加类提示 ATL类只能添加到MFC EXE 和MFC规则DLL项目或完全支持ATL的项目 错误提示解决方式