在 Java 中找不到对象池的现代实现
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3636125/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can't find a modern Implementation of Object Pool in Java
提问by time4tea
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.
我正在寻找 Java 中对象池的现代实现。我可以看到 apache commons 之一,但老实说,我更喜欢使用泛型和来自较新版本的 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!
谢谢!
回答by Pascal Thivent
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.
我可以看到 apache commons 之一,但老实说,我更喜欢使用泛型和来自较新版本的 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).
嗯,事实是这种项目(通用对象池)没有太大吸引力,因为现在几乎不需要它们(对象创建很便宜)。这可能解释了为什么您很少看到它们(实际上,我只知道 Commons Pool)。
That being said, if generics is your primary concern, you could patch Commons Pool, see POOL-83, it has a patch attached.
话虽如此,如果泛型是您的主要关注点,您可以修补 Commons Pool,参见POOL-83,它附带了一个补丁。
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
您没有无限的选择。任何一个
- Find something that does everything you need (I don't know such a library, which doesn't mean there isn't any).
- If you can't find something that does everything you need out of the box, then extend an existing solution.
- Roll your own solution.
- 找到可以满足您所有需求的东西(我不知道这样的库,这并不意味着没有)。
- 如果您找不到开箱即用的功能,请扩展现有的解决方案。
- 推出您自己的解决方案。
回答by emory
Commons Pool is a good candidate for your project.
Commons Pool 是您项目的理想选择。
- 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
- do casting;
- implement a parallel interface that does the casting for you; or
- use the patchthat Pascal identified
- 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.
- Ugly Code- You are supposed to use it, not marry it.
- Custom Liveness Validation- Implement the validateObjectto test the liveness of objects. Dead objects will be destroyed. You can also implement a Crontask to periodically borrow and return objects - forcing the timely elimination of dead objects.
- 泛型接口- 公共池最明显的问题是它的前泛型接口。有多种方法可以解决这个问题。你可以
- 做铸造;
- 实现一个并行接口,为您进行转换;或者
- 使用Pascal 确定的补丁
- 来自最新 java 的 Concurrency Stuff- 这是一个您不应该关心的实现细节。如果并发是正确的,那么正确性是如何实现的并不重要。或者,使用更新的东西但并发性错误的池实现仍然是一个糟糕的候选者。
- 丑陋的代码- 你应该使用它,而不是嫁给它。
- 自定义活性验证- 实现validateObject以测试对象的活性。死对象将被销毁。您还可以实施Cron任务来定期借用和返回对象 - 强制及时消除死对象。
回答by NamshubWriter
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 examplefrom the question mentioned by @codedevour
如果池中的对象数量是固定的,您可以BlockingQueue
在@codedevour 提到的问题中使用本示例中的 a
If the values you want to pool can be associated with a key, you can use MapMakerfrom 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);
}
});
回答by Jeremy Unruh
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.
结帐 KBOP。这是一个线程安全的阻塞单键到单对象或单键到多对象池。它是轻量级的,不添加额外的依赖项。
回答by vanOekel
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).
另一个池(yapool)包含一个通用池实现,可以选择通过侦听器(示例)处理池事件。这在自定义池行为、添加功能和诊断池资源使用方面提供了很大的灵活性。或者,您还可以扩展池实现以添加您自己想要的行为(示例)。这应该相对简单,因为池实现已经相互扩展(基本 --> 绑定 --> 修剪)。
To start, you can use a simple BoundPooland set your own factory (see for example the "LongFactory" in the earlier mentioned pool events example), or just use an ObjectPool.
首先,您可以使用一个简单的BoundPool并设置您自己的工厂(例如参见前面提到的池事件示例中的“LongFactory”),或者只使用ObjectPool。
Yapool has no "synchronized" blocks and is pretty fast.
Yapool 没有“同步”块并且速度非常快。
回答by Christopher Klewes
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?.
这似乎与您的问题有关,也许您真的应该考虑自己编写一个对象池。这个基本的 Java 对象池有效吗?.
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.
池化最初是作为针对对象创建和垃圾收集的缓慢性能而引入的一种调整操作。在现代 JVM > 1.4 上,在典型的业务应用程序中优化内存管理不再需要池化。它甚至会对垃圾收集器的性能产生负面影响。在特殊情况下,比如在每个方法调用中创建数百万个实例,它仍然可以得到回报。
然而,实例池对于具有缓慢自定义“后期构建”的对象仍然很有趣。在某些情况下,您希望在创建对象后注入一些依赖项,读取一些配置等。这可能很慢,而且不必一遍又一遍地执行。在这种情况下,对象池将提高整体性能。
Adam Bien -- Object Pooling Can Be Still Useful - For Entirely Different Reasons
Adam Bien——对象池仍然有用——出于完全不同的原因
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.
您如何看待增强公共池框架?您可以进行一些重构并添加通用部分,对其他人也很好。
回答by user2176913
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...
http://code.google.com/p/spf4j/ 中有一个对象池实现, 我发现它比 apache commons 中的实现更好。代码没那么难看,而且性能更好……
回答by jamiebarrow
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.
对于泛型方面,为什么不直接使用非泛型库,并创建一个用于访问负责转换的非泛型库的包装器?这样就可以在一个地方完成转换,这至少会稍微清理一下代码。
回答by nanda
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
要了解这两者之间的区别,您可以阅读以下内容: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?
我的观点是,我们可以使用缓存库来池我们的对象,但不能反过来。只是不要忘记在我们从缓存中获取对象后重新初始化它。那么,如果您只需使用一种即可实现所有功能,为什么还要使用两种不同的动物(缓存和池)呢?