Problems with SimplePool Pools: An Extended Example

} _currentPosition = startingSize -1; } }

12.3.4 Problems with SimplePool

SimplePool has a number of nice attributes. The first is that, as advertised, the code is straightforward. Another is threadsafety. Since both getObject and returnObject are synchronized, SimplePool is threadsafe. Moreover, because only one thread ever gets to _helper at a time, SimplePool is threadsafe independent of the implementation of PoolHelper . However, SimplePool also has four major problems. First, there is no effective bound on the number of pooled objects that are created. If all the pooled objects are checked out, then another object is created. This can be unfortunate. When our server is really busy, it may spend an inordinate amount of time and resources creating pooled objects that it will then throw away. In the case of database connections, it may swamp the database server as well. The second problem is that getObject and returnObject are both synchronized. Thus, at most, one thread can either get or return an object. This, in turn, has two effects. First, returning an object to the pool, an operation that ought to be quite fast for the client threads, may take a long time. Second, its quite possible that instances of SimplePool will not achieve efficient reuse during peak usage periods. Suppose, for example, that all the pooled objects have been vended, and 15 more requests for objects come in. Its possible that 15 new objects will be created, even if during that same time period, 11 client threads were attempting to return pooled objects. The third major problem with SimplePool is that the validity checks, and the destruction of surplus pooled objects, are done in the calling thread. One of the big benefits of using a pool is that it makes the client threads more responsive by offloading most of their work to the pool. Wed certainly like to move validation and destruction out of the client threads as well. The last major defect with SimplePool is that the pool doesnt shrink during quiet times. Once the pool is at maximum size, it will keep all of its allocated objects forever. Given that pooled objects are usually scarce resources, wed probably like a way to gradually shrink the pool when its not often being used and release those scare resources for other uses. Each of these problems cries out for background threads inside our pooling mechanism. In particular, we will implement three threads: one that handles object creation, another that handles returning objects to the pool, and a third that handles shrinking the pool over time.

12.3.5 The Creation Thread