设计模式之美: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.

结构

参与者

Reusable

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

ReusablePool

  • 管理类的实例。

Client

  • 使用类的实例。

适用性

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

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

效果

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

相关模式

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

实现

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

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

  1 namespace ObjectPoolPattern.Implementation1
2 {
3 public abstract class ObjectPool<T>
4 {
5 private TimeSpan _expirationTime;
6 private Dictionary<T, DateTime> _unlocked;
7 private Dictionary<T, DateTime> _locked;
8 private readonly object _sync = new object();
9
10 public ObjectPool()
11 {
12 _expirationTime = TimeSpan.FromSeconds(30);
13 _locked = new Dictionary<T, DateTime>();
14 _unlocked = new Dictionary<T, DateTime>();
15 }
16
17 public ObjectPool(TimeSpan expirationTime)
18 : this()
19 {
20 _expirationTime = expirationTime;
21 }
22
23 protected abstract T Create();
24
25 public abstract bool Validate(T reusable);
26
27 public abstract void Expire(T reusable);
28
29 public T CheckOut()
30 {
31 lock (_sync)
32 {
33 T reusable = default(T);
34
35 if (_unlocked.Count > 0)
36 {
37 foreach (var item in _unlocked)
38 {
39 if ((DateTime.UtcNow - item.Value) > _expirationTime)
40 {
41 // object has expired
42 _unlocked.Remove(item.Key);
43 Expire(item.Key);
44 }
45 else
46 {
47 if (Validate(item.Key))
48 {
49 // find a reusable object
50 _unlocked.Remove(item.Key);
51 _locked.Add(item.Key, DateTime.UtcNow);
52 reusable = item.Key;
53 break;
54 }
55 else
56 {
57 // object failed validation
58 _unlocked.Remove(item.Key);
59 Expire(item.Key);
60 }
61 }
62 }
63 }
64
65 // no object available, create a new one
66 if (reusable == null)
67 {
68 reusable = Create();
69 _locked.Add(reusable, DateTime.UtcNow);
70 }
71
72 return reusable;
73 }
74 }
75
76 public void CheckIn(T reusable)
77 {
78 lock (_sync)
79 {
80 _locked.Remove(reusable);
81 _unlocked.Add(reusable, DateTime.UtcNow);
82 }
83 }
84 }
85
86 public class DatabaseConnection : IDisposable
87 {
88 // do some heavy works
89 public DatabaseConnection(string connectionString)
90 {
91 }
92
93 public bool IsOpen { get; set; }
94
95 // release something
96 public void Dispose()
97 {
98 }
99 }
100
101 public class DatabaseConnectionPool : ObjectPool<DatabaseConnection>
102 {
103 private string _connectionString;
104
105 public DatabaseConnectionPool(string connectionString)
106 : base(TimeSpan.FromMinutes(1))
107 {
108 this._connectionString = connectionString;
109 }
110
111 protected override DatabaseConnection Create()
112 {
113 return new DatabaseConnection(_connectionString);
114 }
115
116 public override void Expire(DatabaseConnection connection)
117 {
118 connection.Dispose();
119 }
120
121 public override bool Validate(DatabaseConnection connection)
122 {
123 return connection.IsOpen;
124 }
125 }
126
127 public class Client
128 {
129 public static void TestCase1()
130 {
131 // Create the ConnectionPool:
132 DatabaseConnectionPool pool = new DatabaseConnectionPool(
133 "Data Source=DENNIS;Initial Catalog=TESTDB;Integrated Security=True;");
134
135 // Get a connection:
136 DatabaseConnection connection = pool.CheckOut();
137
138 // Use the connection
139
140 // Return the connection:
141 pool.CheckIn(connection);
142 }
143 }
144 }

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

Object Pool的更多相关文章

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

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):实现 DatabaseConnectionPool 类. 实现方式(二):使用对象构造方法和预分配方式实现 ObjectPool ...

  2. .NET Core中Object Pool的简单使用

    前言 复用,是一个重要的话题,也是我们日常开发中经常遇到的,不可避免的问题. 举个最为简单,大家最为熟悉的例子,数据库连接池,就是复用数据库连接. 那么复用的意义在那里呢? 简单来说就是减少不必要的资 ...

  3. What are the differences between Flyweight and Object Pool patterns?

    What are the differences between Flyweight and Object Pool patterns? They differ in the way they are ...

  4. Object Pool 对象池的C++11使用(转)

    很多系统对资源的访问快捷性及可预测性有严格要求,列入包括网络连接.对象实例.线程和内存.而且还要求解决方案可扩展,能应付存在大量资源的情形. object pool针对特定类型的对象循环利用,这些对象 ...

  5. 对象池模式(Object Pool Pattern)

    本文节选自<设计模式就该这样学> 1 对象池模式的定义 对象池模式(Object Pool Pattern),是创建型设计模式的一种,将对象预先创建并初始化后放入对象池中,对象提供者就能利 ...

  6. Unity Object Pool完全体

    using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; public ...

  7. [译]Unity3D内存管理——对象池(Object Pool)

    原文地址:C# Memory Management for Unity Developers (part 3 of 3), 其实从原文标题可以看出,这是一系列文章中的第三篇,前两篇讲解了从C#语言本身 ...

  8. Java小对象的解决之道——对象池(Object Pool)的设计与应用

    一.概述 面向对象编程是软件开发中的一项利器,现已经成为大多数编程人员的编程思路.很多高级计算机语言也对这种编程模式提供了很好的支持,例如C++.Object Pascal.Java等.曾经有大量的软 ...

  9. thinking in object pool

    1.背景 对象池为了避免频繁创建耗时或耗资源的大对象,事先在对象池中创建好一定数量的大对象,然后尽量复用对象池中的对象,用户用完大对象之后放回对象池. 2.问题 目前纵观主流语言的实现方式无外乎3个步 ...

随机推荐

  1. Java设计模式偷跑系列(十八)建模和责任链模式的实现

    转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/40018231 责任链模式(ChainOfResponsibility): 有多个对象,每一 ...

  2. C#如何设置session过期时间

    1.操作系统  步骤:开始——〉管理工具——〉Internet信息服务(IIS)管理器——〉网站——〉默认网站——〉  右键“属性”——〉主目录——〉配置——〉选项——〉启用会话状态——〉会话超时(在 ...

  3. 浅谈JavaScript中的柯里化函数

    首先,不可避免的要引经据典啦,什么是柯里化函数呢(from baidu): 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返 ...

  4. C# 跨线程呼叫控制

    在C# 应用程序开发, 我们经常要UI作线程分开,防止界面停止响应.  同一时候我们又须要在工作线程中更新UI界面上的控件, 以下介绍几种经常使用的方法 阅读文件夹 线程间操作无效 第一种办法:禁止编 ...

  5. Oracle 免费的数据库

    Oracle 免费的数据库--Database 快捷版 11g 安装使用与"SOD框架"对Oracle的CodeFirst支持 一.Oracle XE 数据库与连接工具安装使用 O ...

  6. .Net 2.0实例学习:WebBrowser页面与WinForm交互技巧

    原文:.Net 2.0实例学习:WebBrowser页面与WinForm交互技巧 最近看到博客园入门教学文章比较流行,自己最近又偷懒比较多,没啥心得,不妨写一篇没啥深度的入门文章吧. 话说有了WebB ...

  7. 关于WebBrowser.DocumentCompleted事件

    原文:关于WebBrowser.DocumentCompleted事件 今天发现使用WebBrowser时载入一个页面后DocumentCompleted事件会被调用2次,后来发现这两次WebBrow ...

  8. 给Notepad++ 6.7 加右键菜单带图标

    使用的是Notepad++ 6.7,下载 NppShell64.dll 和 NppShell.dll方法:将BAT文件和下载的NppShell64.dll 和 NppShell.dll放置Notepa ...

  9. 谈论quick-cocos2d-x和cocos2d-x lua了解差异

    之前说,我把这个两个词区别.经过太长时间.当然,反击的麻烦.quick-cocos2d-x它提到quick,cocos2d-x lua姑且称为本地lua对. 我认为,首先与这两个小的朋友接触会跟着或多 ...

  10. CreateMutex

    C++ API CreateMutex 找出当前系统是否已经存在指定进程的实例.假设没有则创建一个相互排斥体.CreateMutex()函数可用来创建一个有名或无名的相互排斥量对象. HANDLE C ...