8

我并不一定意味着使用单例模式来实现,而是仅具有和使用池的一个实例。我不喜欢只有一个池(或每个池类型一个)的想法。但是,我真的无法想出任何具体情况,其中多个池对可变类型有优势,至少在单个池可以正常工作的情况下不是这样。

与单例池相比,拥有多个池有什么优势?

4

3 回答 3

3

是的,拥有多个对象池肯定有潜在的原因 - 特别是,您可能希望让一个池有资格进行垃圾收集(或手动释放它等),同时保留其他池。

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

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

于 2011-02-09T19:28:29.987 回答
2

与单例池相比,拥有多个池有什么优势?

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

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

应用程序池

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

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

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

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

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

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

连接池

在 SQL Server 中,对数据库的多次调用使用连接池来避免在每次查询时创建新数据库连接的开销,但是 SQL Server会为每个连接字符串创建一个新池。我想这种设计背后的基本原理如下:

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

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

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

如何设计一个游泳池

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

如果你有一个非常简单的对象池,你也许可以摆脱单例设计。如果你真的需要额外的灵活性、定制化,或者你有一个真正独特的设置,比如分布在多个进程或机器上的对象池,那么你肯定会从 n-gleton 设计中受益。

于 2011-02-09T22:55:34.573 回答
0

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

public class MyClass
{
    public static MyClass GetInstance()
    {
          return singleton_ ?? (singleton = new MyClass());
    }
}
于 2011-02-13T15:21:20.053 回答