The initial-resource creation strategy The difference between the steady-state size and the maximum-pool size

_owner.removeAnObject ; resetClock ; } } } } private synchronized void resetClock { _timeLeftUntilWeShrinkThePool = DEFAULT_TIME_TO_WAIT; } private synchronized void decrementClock { _timeLeftUntilWeShrinkThePool-= DEFAULT_TIME_INTERVAL; if 0 _timeLeftUntilWeShrinkThePool { _timeLeftUntilWeShrinkThePool = 0; } } } The last thread we added, which shrinks the pool, is somewhat inefficient. It counts constantly, even if the pool has already been reduced to its steady-state size. It can be easily argued that having a thread do nothing, and do nothing repeatedly, is a bad design. This suggests two possible modifications to our design. The first is that we make the thread wait once steady state is reached. That is, we add a lock object and have the shrinking thread wait on it the thread would get notified the next time an object is actually created. This can easily be implemented within ThreadPool_Final . A second, more interesting design change, is to eliminate the idea of a steady-state size entirely. Right now, the shrinker thread checks two things: whether the pool has had objects in it continually for a long period of time and whether the pool is larger than its steady state. If so, an object is pulled from the pool and destroyed. We could easily change this behavior so that the thread monitors the pool constantly and removes any objects it thinks are surplus, regardless of the pools size.

12.3.8 Two Additional Considerations When Implementing a Pool

While this example has gone on long enough, there are two additional factors you should consider when implementing a pool:the initial-resource creation strategy andthe difference between the steady-state size and the maximum-pool size.

12.3.8.1 The initial-resource creation strategy

In our example, we used a lazy creation strategy and only created objects when they were needed. That is, when the pool is created, it contains no objects. And it will continue to be empty until a client thread makes a request for a resource. The alternative strategy is to have the creation thread fill the pool immediately by creating resource objects. This doesnt make much of a difference in practice. I prefer a lazy creation strategy simply because Id rather not create a lot of extra objects when the server launches or in servers that are lightly used. But, if you think that a lazy creation strategy may have a noticeable impact on either perceived or actual server performance, you should consider either immediately filling the pool up to its steady-state size, or adding a third variable to control how many objects to immediately create when the pool is created.

12.3.8.2 The difference between the steady-state size and the maximum-pool size

Suppose you implement a database connection pool with a steady-state size of 10 connections and a maximum size of 15 connections. Further suppose that, at some point, your server already has 10 transactions open and needs to use another database connection. In all the implementations weve discussed, the pool will create the database connection right away. The problem is this: its quite possible that your server needs the extra database connection because its currently handling an unusually heavy load. In which case, creating extra database connections may be a really bad idea™it amounts to deciding that the currently pending requests ought to slow down while extra database connections are created. A better strategy might be: If the server is really busy, all new database requests are put on hold and not serviced by additional database connections. If you decide to use the second strategy, you can implement it easily enough™just set the steady-state size equal to the maximum-pool size.

12.4 Some Final Words on Threading