对象池有什么理由不被视为单例吗?
我并不一定意味着使用单例模式来实现,而是仅拥有并使用池的一个实例。我不喜欢只有一个池(或每个池类型一个)的想法。然而,我确实无法想出任何具体情况,其中多个池对于可变类型有优势,至少在单个池可以发挥同样作用的情况下。
与单个池相比,拥有多个池有什么优势?
I don't necessarily mean implemented using the singleton pattern, but rather, only having and using one instance of a pool. I don't like the idea of having just one pool (or one per pooled type). However, I can't really come up with any concrete situations where there's an advantage to multiple pools for mutable types, at least not any where a single pool can function just as well.
What advantages are there to having multiple pools over a singleton pool?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,拥有多个对象池肯定有潜在的原因 - 特别是,您可能希望让一个池有资格进行垃圾回收(或手动释放它等),同时保留其他对象池。
例如,考虑字符串的对象池。这在 XML 上下文中可能非常方便 - 如果您正在解析相同架构的多个 XML 文档,您很可能希望合并用于元素和属性名称的字符串。但是,一旦您完成了处理这些名称的部分,这些名称可能永远不会再次使用 - 因此,当您转移到另一组文档时,您可能需要使用不同的池。您最终可能会同时执行这两项任务,在这种情况下,让两个池同时可用会很有用。
或者考虑线程池 - 我认为 .NET 线程池实现的一个缺点是基本上只有一个系统线程池。我喜欢在服务器中拥有多个线程池的想法 - 一些线程用于低优先级批处理作业,一些线程用于“正常”请求,一些高优先级线程用于运行状况监控等作业。
Yes, there are definitely potential reasons for having multiple object pools - in particular, you may want to let one pool become eligible for garbage collection (or manually free it etc) while keeping other ones.
For example, consider an object pool for strings. That may be really handy in the context of XML - if you're parsing several XML documents of the same schema, you quite possibly want to pool the strings used for the element and attribute names. However, once you've finished that part of processing those names may never be used again - so as you move onto a different set of documents, you may want to use a different pool. You may end up doing both tasks at once, in which case it's useful to have both pools available simultaneously.
Or consider thread pools - I consider it a downside of the .NET thread pool implementation that there's basically just one system thread pool. I like the idea of being able to have multiple thread pools in a server - some threads for low priority batch jobs, some for "normal" requests, and a few high priority threads for jobs like health monitoring.
我认为我们使用的大多数对象池(例如 ThreadPool)为了简单起见都被实现为单例:在这种情况下,这些池的设计者也没有看到多实例池的用途。
然而,有一些地方我们确实拥有多个池:IIS 应用程序池和数据库连接池。
应用程序池
在 IIS 中,您可以配置多个应用程序池,以便相关的 Web 应用程序都在自己的池中运行。这种设计有几个优点,并且这些优点可以推广到 IIS 之外的池实现:
多个对象池允许一定程度的隔离,因此一个池中的错误不应影响其他池中的对象。 多个对象池
每个池可以在不同的用户下运行,这根据您的应用程序池为您提供不同的安全级别。
每个池可以有不同的错误处理程序。
每个池都可以使用不同版本的 .NET 框架运行。
每个池都可以有自己的 HTTP 超时。
连接池
在 SQL Server 中,对数据库的多次调用使用连接池来避免在每个查询上创建新数据库连接的开销,但是 SQL Server 为每个连接字符串创建一个新池。我想这种设计背后的基本原理如下:
每个池都拥有与特定数据库实例的连接。如果只有一个池包含所有连接,那么它将需要搜索所有连接,直到找到与您请求的连接字符串匹配的连接。由于每个连接字符串有多个池,因此更容易从该特定池中提取第一个可用连接,而无需搜索其他连接。
也就是说,我怀疑SQL Server使用多个连接池作为快速抓取数据库连接的优化。
也就是说
我还可以想象,所有这些连接可能共享一些特定于其连接池的资源,这对于单个池来说可能是不可能的。例如,您可以指定每个连接字符串的最大连接池大小;您可能无法使用单池设计来控制与特定数据库的同时连接数。
如何设计水池
如果不考虑设计中的真正需求,您就无法真正选择是拥有多个水池还是单个水池。
如果您有一个非常简单的对象池,您可能可以摆脱单例设计。如果您确实需要额外的灵活性、自定义,或者您可能有一个真正独特的设置,例如分布在多个进程或机器上的对象池,那么您肯定会从 n-gleton 设计中受益。
I supposed most object pools we use, like the ThreadPool, are implemented as singletons for simplicity: in that, the designers of those pools didn't see a purpose in multiple-instance pools either.
However, there are a handful of places where we really do have multiple pools: IIS application pools and database connection pools.
App pools
In IIS, you can configure multiple application pools, so that related web applications all run in their own pool. There are a couple of advantages to this design, and the advantages can generalize to pool implementations outside of IIS:
Multiple object pools allow for some degree of isolation, so an error in one pool should not have an impact on objects in other pools.
Each pool can run under a different user, which gives you different levels of security based on your application pool.
Each pool can have a different handler for errors.
Each pool can run with a different version of the .NET framework.
Each pool can have its own HTTP timeout.
Connection pools
In SQL Server, multiple calls to a database use connection pooling to avoid the overhead of creating a new database connection on every query, however SQL Server creates a new pool per connection string. I imagine the rationale behind this design is as follows:
Each pool holds a connection to a specific database instance. If there were only one pool containing all the connections, then it would need search through all the connections until it finds the connection matching the connection string you've requested. Since there are multiple pools per connection string, its easier to pull the first available connection from that particular pool without searching through other connections.
In other words, I suspect SQL Server uses multiple connection pools as an optimization to quickly grab a database connection.
I can also imagine that all of those connections probably share some resources specific to their connection pool, which may not be possible with a single pool. For example, you can specify the maximum connection pool size per connection string; you may not be able to control the number of simultaneous connections to a particular database using a single-pool design.
How to design a pool
You can't really choose whether to have multiple pools or a single pool without looking at what you really need from your design.
If you have a very simple object pool, you might be able to get away with a singleton design. If you really need extra flexibility, customization, or maybe you have a really unique setup like an object pool distributed across multiple processes or machines, you would definitely benefit from an n-gleton design instead.
如果您仔细地实现单例模式,您以后可能会改变主意。只需将类的单例性封装在工厂方法后面即可。如果一切都使用它,那么当你有充分的理由时,你可以允许它有多个实例。
If you implement a singleton pattern carefully, you can change your mind later. Just encapsulate your class's singleton-ness behind a factory method. If everything uses that, then you can allow it to have multiple instances later, when you have a good reason.