Can't find a modern Implementation of Object Pool in Java [closed]
Asked Answered
B

9

38

I'm looking for a modern implementation of an object pool in Java. I can see the apache commons one, but to be honest, I'd rather one that uses generics, and the concurrency stuff from more recent versions of java.

Does the commons pool really work well? The code looks pretty, erm, ugly.

I'd need something that allows custom liveness validation etc etc.

Thanks!

Bidget answered 3/9, 2010 at 13:21 Comment(10)
Why do you need an object pool first of all? In modern JVMs, creation of small objects is very, very cheap. Effective Java 2nd Ed. Item 5 recommends object pools only for heavyweight object like DB connections.Phalan
Well - i've got something like a database connection (but not a database connection), that I'd like to pool.Bidget
(hence the bit about liveness validation)Bidget
Can you list some more requirements that apache-commons can't meet? Seems like thread-safety is one of them. Any others?Alex
its not so much that it can't meet them... it just seems so... old. For example the interfaces are not generified, so you just get "Object". GenericObjectPool just feels like its kinda outdated and crufty. I just assumed there must be a 'cleaner' implementation aroundBidget
But the reason it's old is because they are pretty much unnecessary. Besides, old just implies stable ;)Slapdash
why are they unnecessary? (not trolling!) these are expensive objects to external resources. you use a database connection pool, right? i want a (something else) connection pool...Bidget
@Rulmeq "pretty much unnecessary" does not mean "never necessary". Library authors do not always get it right.Desiredesirea
commons-pool supports generics nowZeuxis
Here is a discussion about this in Guava: code.google.com/p/guava-libraries/issues/detail?id=683Underfoot
M
19

I can see the apache commons one, but to be honest, I'd rather one that uses generics, and the concurrency stuff from more recent versions of java.

Well, the fact is that this kind of projects (generic object pools) don't get much traction because there is little need for them nowadays (object creation is cheap). This probably explains why you don't see much of them (and actually, I'm only aware of Commons Pool).

That being said, if generics is your primary concern, you could patch Commons Pool, see POOL-83, it has a patch attached.

Does the commons pool really work well? The code looks pretty, erm, ugly.

It does have a few known bugs (four) but, to my knowledge, it works. And regarding the last sentence, well, if you think you can write something better, and if you have the time for that, why not just doing it?

I'd need something that allows custom liveness validation etc etc.

You don't have an infinite number of options. Either

  1. Find something that does everything you need (I don't know such a library, which doesn't mean there isn't any).
  2. If you can't find something that does everything you need out of the box, then extend an existing solution.
  3. Roll your own solution.
Marshallmarshallese answered 7/9, 2010 at 10:18 Comment(5)
Thanks for your answer - I'm fully aware that object creation, per se, is very cheap. I would never use an object pool to reuse object that exist only in memory. There be dragons. However, often objects represent some external expensive-to-create resource that you cannot create cheaply. Think database connection, or SSL connection. Its this type of think that I'd like to pool. I have updated the commons pool code. I'll post a patch here or something.Bidget
@Bidget I was just trying to anchor my answer, not implying that you weren't aware. But thanks for the feedback and making the patch available.Marshallmarshallese
@PascalThivent I agree that object creation is cheap, but object initialization may be expensive. In other words, exactly the same as database connections.Desiredesirea
I'm failing to see how object creation being cheap, which seems to be mentioned a lot in this question, has anything to do with object pools being made redundant. Cheapness has to be paired with the number of times it occurs, a grain of rice is cheap on its own but if you buy tonnes of it is expensive. Object pools are therefore useful when object creation becomes a bottleneck which varies depending on the number of initialisations and not just the cost of a single initialisation.Transcend
Object creation is expensive. People conclude that object creation is cheap basing in microbenchmarks, where JVM can often elide object creation through escape analysis and even if not, cache effects or GC don't matter much. In real code object creation is slow and should be avoided as much as possible - object creation is often followed by a cache miss because it uses a chunk of memory that hasn't been touched for a while. It also forces GC to run more frequently, making it more likely to promote objects to the old gen, etc. This way you can slow your programs by 20x vs stack based code.Samford
L
7

Commons Pool is a good candidate for your project.

  1. Generics Interface - The most obvious problem with commons pool is its pre-generics interface. There are a number of ways you can get around this. You can
    1. do casting;
    2. implement a parallel interface that does the casting for you; or
    3. use the patch that Pascal identified
  2. Concurrency Stuff from more recent java - This is an implementation detail you should not care about. If the concurrency is correct, then it does not matter how correctness was achieved. Alternatively, a pool implementation that uses the more recent stuff but whose concurrency is wrong is still a poor candidate.
  3. Ugly Code - You are supposed to use it, not marry it.
  4. Custom Liveness Validation - Implement the validateObject to test the liveness of objects. Dead objects will be destroyed. You can also implement a Cron task to periodically borrow and return objects - forcing the timely elimination of dead objects.
League answered 11/9, 2010 at 8:21 Comment(1)
I don't think concurrency is an implementation detail you shouldn't care about; you would only use an object pool if you want improved performance, so why would you use expensive monitor synchronization in this case when lock/wait free data structures are available?Vulnerable
G
7

It's hard to make a recommendation without knowing what features you need.

If the number of objects in the pool is fixed, you can use a BlockingQueue as in this example from the question mentioned by @codedevour

If the values you want to pool can be associated with a key, you can use MapMaker from Guava

ConcurrentMap<Key, Connection> connections = new MapMaker()
       .concurrencyLevel(32)
       .softKeys()
       .weakValues()
       .expiration(30, TimeUnit.MINUTES)
       .evictionListener(
           new MapEvictionListener<Key, Connection>() {
             public onEviction(Key key, Connection connection) {
               connection.close();
             } 
           });
       .makeComputingMap(
           new Function<Key, Connection>() {
             public Connection apply(Key key) {
               return createConnection(key);
             }
           });
Gown answered 11/9, 2010 at 15:41 Comment(4)
i love this example of MapMaker. It doesn't do what i need this time though!Bidget
What features do you need from the object pool? What is it used for?Gown
Looks like this way to use MapMaker is being migrated to CacheBuilder. code.google.com/p/guava-libraries/wiki/MapMakerMigrationDesiredesirea
And this is one of the code snippets that hopefully will be much shorter in Java 8.Desiredesirea
S
3

Checkout KBOP. It's a thread safe blocking single key to single object or single key to multi object pool. It's lightweight and add no extra dependencies.

http://www.kbop.org

Study answered 21/4, 2013 at 17:51 Comment(1)
Dead domain. Github page: github.com/gondor/kbopSilk
T
2

This seems to be related to your question, maybe you should really consider to write a object pool by your own. Does this basic Java object pool work?.

Pooling was initially introduced as a tuning action for the slow performance of object creation and garbage collection in particular. On a modern JVM > 1.4 pooling is no more needed for the optimization of memory management in a typical business application. It can even have a negative effect on the garbage collector performance. In special cases, like creating millions of instances in every method call, it could still pay off.

Instance pooling, however is still interesting for objects with slow custom "post construction". In some cases you want to inject some dependencies after the object creation, read some configuration etc. This can be slow and doesn't have to be performed over and over again. In such cases object pooling will improve the overall performance.

Adam Bien -- Object Pooling Can Be Still Useful - For Entirely Different Reasons

What do you think of enhancing the commons Pool Framework? You could do some refactoring and add the generic part, would be nice for others too.

Tocantins answered 10/9, 2010 at 14:1 Comment(0)
G
2

Yet another pool (yapool) contains a generic pool implementation with the option to act on pool events via listeners (example). This provides a lot of flexibility in customizing pool behavior, add functions and diagnosing pool resource usage. Alternatively, you can also extend a pool implementation to add your own desired behavior (example). This should be relatively straightforward since pool implementations already extend each other (Basic --> Bound --> Pruned).

To start, you can use a simple BoundPool and set your own factory (see for example the "LongFactory" in the earlier mentioned pool events example), or just use an ObjectPool.

Yapool has no "synchronized" blocks and is pretty fast.

Guyguyana answered 8/12, 2013 at 15:33 Comment(0)
U
1

There is a object pool implementation in http://code.google.com/p/spf4j/ I find it a better implementation than the one in apache commons. Code is not so ugly, and it performs better...

Udall answered 16/3, 2013 at 11:50 Comment(0)
H
0

For the generics side, why not just use the non-generic library, and create a wrapper that you use to access the non-generic library that takes care of the casting? That way there's a single place where the casting is done, which will at least clean up the code a bit.

Hemipterous answered 13/9, 2010 at 8:50 Comment(0)
V
-4

To pool is the traditional way, to cache is the modern way. And there are many modern implementation of cache out there.

To learn the different between those two, you can read this: http://www.informit.com/guides/content.aspx?g=java&seqNum=104

My view is, we can use a cache library to pool our objects but not the other way around. Just don't forget to re-initialize the object after we get it from the cache. So why bother having two different animals (cache and pool) if you can achieve all just using one?

Vincentia answered 8/9, 2010 at 3:49 Comment(2)
thanks. almost no information there.Bidget
Maybe he's talking about distributed caching. Something like memcached? I guess that's a 'pool' of resources, in a way.Hemipterous

© 2022 - 2024 — McMap. All rights reserved.