zoukankan      html  css  js  c++  java
  • Object Pool

    设计模式之美: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 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

  • 相关阅读:
    IP应用加速技术详解:如何提升动静混合站点的访问速率?
    阿里云PolarDB发布重大更新 支持Oracle等数据库一键迁移上云
    BigData NoSQL —— ApsaraDB HBase数据存储与分析平台概览
    洛谷P1457 城堡 The Castle
    洛谷P1461 海明码 Hamming Codes
    洛谷P1460 健康的荷斯坦奶牛 Healthy Holsteins
    洛谷P1459 三值的排序 Sorting a Three-Valued Sequence
    洛谷P1458 顺序的分数 Ordered Fractions
    洛谷P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib
    洛谷P1215 [USACO1.4]母亲的牛奶 Mother's Milk
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3667864.html
Copyright © 2011-2022 走看看