我正在寻找 Java 中对象池的现代实现。我可以看到 apache commons 之一,但老实说,我更喜欢使用泛型的,以及最新版本的 java 中的并发内容。
公共池真的好用吗?代码看起来很漂亮,呃,丑陋。
我需要一些允许自定义活性验证等的东西。
谢谢!
我正在寻找 Java 中对象池的现代实现。我可以看到 apache commons 之一,但老实说,我更喜欢使用泛型的,以及最新版本的 java 中的并发内容。
公共池真的好用吗?代码看起来很漂亮,呃,丑陋。
我需要一些允许自定义活性验证等的东西。
谢谢!
我可以看到 apache commons 之一,但老实说,我更喜欢使用泛型的,以及最新版本的 java 中的并发内容。
好吧,事实是这种项目(通用对象池)并没有受到太大的关注,因为现在很少需要它们(对象创建很便宜)。这可能解释了为什么您看不到它们(实际上,我只知道 Commons Pool)。
话虽这么说,如果泛型是您最关心的问题,您可以修补 Commons Pool,请参阅POOL-83,它附带了一个补丁。
公共池真的好用吗?代码看起来很漂亮,呃,丑陋。
它确实有一些已知的错误(四个),但据我所知,它可以工作。关于最后一句话,好吧,如果你认为你可以写出更好的东西,如果你有时间,为什么不直接写呢?
我需要一些允许自定义活性验证等的东西。
你没有无限数量的选择。任何一个
Commons Pool 是您项目的理想选择。
在不知道您需要什么功能的情况下很难做出推荐。
如果池中的对象数量是固定的,您可以使用@codedevour 提到的问题中的BlockingQueue
本例中的 a
如果您要合并的值可以与键关联,则可以使用来自Guava的MapMaker
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);
}
});
结帐 KBOP。这是一个线程安全的阻塞单个对象的单键或多对象池的单键。它是轻量级的,不添加额外的依赖项。
这似乎和你的问题有关,也许你真的应该考虑自己写一个对象池。这个基本的 Java 对象池可以工作吗?.
池化最初是作为一种调优操作引入的,特别是针对对象创建和垃圾收集的缓慢性能。在现代 JVM > 1.4 上,对于典型业务应用程序中的内存管理优化不再需要池化。它甚至会对垃圾收集器的性能产生负面影响。在特殊情况下,例如在每个方法调用中创建数百万个实例,它仍然可以获得回报。
然而,实例池对于自定义“后期构建”缓慢的对象仍然很有趣。在某些情况下,您想在对象创建后注入一些依赖项,读取一些配置等。这可能很慢,并且不必一遍又一遍地执行。在这种情况下,对象池将提高整体性能。
Adam Bien——对象池仍然有用——出于完全不同的原因
您如何看待增强公共池框架?您可以进行一些重构并添加通用部分,对其他人也很好。
另一个池(yapool)包含一个通用池实现,可以选择通过侦听器对池事件进行操作(示例)。这为自定义池行为、添加功能和诊断池资源使用情况提供了很大的灵活性。或者,您还可以扩展池实现以添加您自己想要的行为(示例)。这应该相对简单,因为池实现已经相互扩展(基本 --> 绑定 --> 修剪)。
首先,您可以使用简单的BoundPool并设置您自己的工厂(例如参见前面提到的池事件示例中的“LongFactory”),或者只使用ObjectPool。
Yapool 没有“同步”块,而且速度非常快。
http://code.google.com/p/spf4j/中有一个对象池实现, 我发现它比 apache commons 中的实现更好。代码没那么难看,而且性能更好……
对于泛型方面,为什么不只使用非泛型库,并创建一个用于访问负责转换的非泛型库的包装器?这样,只有一个地方可以完成转换,这至少会稍微清理一下代码。
池化是传统方式,缓存是现代方式。那里有许多现代的缓存实现。
要了解这两者之间的区别,您可以阅读以下内容: http: //www.informit.com/guides/content.aspx?g=java &seqNum=104
我的观点是,我们可以使用缓存库来池化我们的对象,但不能反过来。只是不要忘记在我们从缓存中获取对象后重新初始化它。那么,如果您只需使用一种动物就可以实现所有目标,为什么还要使用两种不同的动物(缓存和池)呢?