Is there any reason for an object pool to not be treated as a singleton?

3.1k views Asked by At

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?

3

There are 3 answers

1
Juliet On BEST ANSWER

What advantages are there to having multiple pools over a singleton pool?

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.

4
Jon Skeet On

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.

1
tallseth On

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.

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