是否有任何理由不将对象池视为单例?

时间:2011-02-09 19:24:23

标签: design-patterns architecture singleton object-pooling

我不一定是指使用单例模式实现,而是仅使用和使用一个池实例。我不喜欢只有一个池(或每个池类型一个)的想法。但是,我无法真正提出任何具体情况,其中多个池对于可变类型具有优势,至少不是任何单个池可以正常运行的地方。

在单个池上拥有多个池有什么优势?

3 个答案:

答案 0 :(得分:3)

是的,确实存在多个对象池的潜在原因 - 特别是,您可能希望让一个池符合垃圾收集条件(或手动释放它等),同时保留其他池。

例如,考虑字符串的对象池。这在XML的上下文中可能非常方便 - 如果您正在解析同一模式的多个XML文档,您很可能想要汇集用于元素和属性名称的字符串。但是,一旦完成处理的那部分,这些名称可能永远不会再次使用 - 因此当您移动到另一组文档时,您可能希望使用不同的池。您最终可能会同时执行这两项任务,在这种情况下,同时提供两个池是很有用的。

或者考虑线程池 - 我认为它是.NET线程池实现的缺点,基本上只有一个系统线程池。我喜欢能够在服务器中拥有多个线程池的想法 - 一些线程用于低优先级批处理作业,一些用于“正常”请求,一些高优先级线程用于健康监控等工作。

答案 1 :(得分:2)

  

有什么好处   单个池上的多个池?

我认为我们使用的大多数对象池(如ThreadPool)都是为了简单而实现为单例:在这种情况下,这些池的设计者也没有在多实例池中看到目的。

但是,有一些地方我们确实拥有多个池:IIS应用程序池和数据库连接池。

应用程序池

在IIS中,您可以配置多个应用程序池,以便相关的Web应用程序都在自己的池中运行。这种设计有几个优点,优点可以归结为IIS之外的池实现:

  • 多个对象池允许某种程度的隔离,因此一个池中的错误不应对其他池中的对象产生影响。

  • 每个池都可以在不同的用户下运行,根据您的应用程序池提供不同级别的安全性。

  • 每个池都可以有不同的错误处理程序。

  • 每个池都可以使用不同版本的.NET框架运行。

  • 每个池都有自己的HTTP超时。

连接池

在SQL Server中,对数据库的多次调用使用连接池来避免在每个查询上创建新数据库连接的开销,但SQL Server creates a new pool per connection string。我想这个设计背后的基本原理如下:

  • 每个池都包含与特定数据库实例的连接。如果只有一个池包含所有连接,则需要搜索所有连接,直到找到与您请求的连接字符串匹配的连接。由于每个连接字符串有多个池,因此更容易从该特定池中提取第一个可用连接,而无需搜索其他连接。

  • 换句话说,我怀疑SQL Server使用多个连接池作为优化来快速获取数据库连接。

  • 我还可以想象所有这些连接可能共享一些特定于其连接池的资源,这对于单个池可能是不可能的。例如,您可以指定每个连接字符串的最大连接池大小;您可能无法使用单池设计控制到特定数据库的同时连接数。

如何设计游泳池

如果没有查看设计中真正需要的内容,您无法真正选择是拥有多个池还是单个池。

如果你有一个非常简单的对象池,你可能可以使用单例设计。如果你真的需要额外的灵活性,自定义,或者你有一个非常独特的设置,比如分布在多个进程或机器上的对象池,你肯定会受益于n-gleton设计。

答案 2 :(得分:0)

如果仔细实施单例模式,您可以稍后改变主意。只需将您的类的单例封装在工厂方法后面。如果一切都使用了它,那么当你有充分的理由时,你可以允许它稍后有多个实例。

public class MyClass
{
    public static MyClass GetInstance()
    {
          return singleton_ ?? (singleton = new MyClass());
    }
}