在Java中找不到现代的Object Pool实现

时间:2010-09-03 13:21:31

标签: java multithreading object-pooling

我正在寻找Java中对象池的现代实现。我可以看到apache commons one,但说实话,我更倾向于使用泛型,以及来自更新版本java的并发内容。

公共泳池真的有效吗?代码看起来很漂亮,呃,丑陋。

我需要一些允许自定义活动验证等的东西。

谢谢!

9 个答案:

答案 0 :(得分:19)

  

我可以看到apache公共一个,但说实话,我宁愿使用泛型,以及来自更新版本的java的并发内容。

嗯,事实是这种项目(通用对象池)并没有太大的吸引力,因为现在对它们的需求很少(对象创建很便宜)。这可能解释了为什么你没有看到太多(实际上,我只知道Commons Pool)。

话虽如此,如果泛型是您的主要关注点,您可以修补Commons Pool,请参阅POOL-83,它附有补丁。

  

公共泳池真的有效吗?代码看起来很漂亮,呃,丑陋。

确实有一些known bugs(四个),但据我所知,它有效。关于最后一句,好吧,如果你认为你可以写出更好的东西,如果你有时间,为什么不这样做呢?

  

我需要一些允许自定义活动验证等的东西。

您没有无限多个选项。任

  1. 找到能满足你所​​需要的东西(我不知道这样的库,这并不意味着没有)。
  2. 如果找不到能满足您需求的所有内容,请扩展现有解决方案。
  3. 推出自己的解决方案。

答案 1 :(得分:7)

Commons Pool是您项目的理想选择。

  1. 泛型接口 - commons池最明显的问题是它的pre-generics接口。有很多方法可以解决这个问题。您可以
    1. 做铸造;
    2. 实现一个为您进行投射的并行接口;或
    3. 使用Pascal识别的patch
  2. 来自更新的java的并发资料 - 这是您不应该关心的实现细节。如果并发性是正确的,则无论如何实现正确性都无关紧要。或者,使用更新的东西但其并发性错误的池实现仍然是一个不好的候选者。
  3. 丑陋的代码 - 你应该使用它,而不是嫁给它。
  4. 自定义生命周期验证 - 实施validateObject以测试对象的活跃度。死亡的物体将被摧毁。您还可以实施Cron任务来定期借用和返回对象 - 强制及时消除死对象。

答案 2 :(得分:7)

如果不知道您需要哪些功能,很难提出建议。

如果池中的对象数量是固定的,您可以使用BlockingQueue中的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); } }); ,如@codedevour提到的问题中的this example

如果要汇总的值可以与密钥相关联,则可以使用MapMaker中的Guava

{{1}}

答案 3 :(得分:3)

结帐KBOP。它是一个线程安全的阻止单个对象的单个键或多个对象池的单个键。它是轻量级的,不添加额外的依赖项。

http://www.kbop.org

答案 4 :(得分:2)

这似乎与您的问题有关,也许您应该考虑自己编写一个对象池。 Does this basic Java object pool work?

  

池最初是作为调整操作引入的,特别是对象创建和垃圾收集的缓慢性能。在现代JVM上> 1.4典型业务应用程序中的内存管理优化不再需要池化。它甚至可能对垃圾收集器性能产生负面影响。在特殊情况下,比如在每个方法调用中创建数百万个实例,它仍然可以获得回报。

     

实例池对于具有慢定制“post post”的对象仍然很有趣。在某些情况下,您希望在创建对象后注入一些依赖项,读取一些配置等。这可能很慢,不必一次又一次地执行。在这种情况下,对象池将提高整体性能。

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

您如何看待增强公共池框架?你可以做一些重构并添加通用部分,对其他人也会很好。

答案 5 :(得分:2)

另一个池(yapool)包含一个通用池实现,可以选择通过侦听器(example)对池事件进行操作。这为自定义池行为,添加功能和诊断池资源使用提供了很大的灵活性。或者,您也可以扩展池实现以添加您自己想要的行为(example)。这应该相对简单,因为池实现已经相互扩展(Basic - &gt; Bound - &gt; Pruned)。

首先,您可以使用简单的BoundPool并设置自己的工厂(请参阅前面提到的池事件示例中的“LongFactory”),或者只使用ObjectPool

Yapool没有“同步”块,速度非常快。

答案 6 :(得分:1)

http://code.google.com/p/spf4j/中有一个对象池实现 我发现它比apache commons中的更好。 代码不是那么难看,它表现得更好......

答案 7 :(得分:0)

对于泛型方面,为什么不使用非泛型库,并创建一个包装器,用于访问负责转换的非通用库?这样就有一个完成转换的地方,至少会清理一下代码。

答案 8 :(得分:-4)

池是传统的方式,缓存是现代的方式。并且有很多现代的缓存实现。

要了解这两者之间的差异,您可以阅读:http://www.informit.com/guides/content.aspx?g=java&seqNum=104

我的观点是,我们可以使用缓存库来汇集我们的对象,但不是相反。在从缓存中获取对象后,不要忘记重新初始化对象。那么,如果只使用一只动物就可以实现所有动物(缓存和游泳池),那么为什么呢?