37

我正在寻找 Java 中对象池的现代实现。我可以看到 apache commons 之一,但老实说,我更喜欢使用泛型的,以及最新版本的 java 中的并发内容。

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

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

谢谢!

4

9 回答 9

18

我可以看到 apache commons 之一,但老实说,我更喜欢使用泛型的,以及最新版本的 java 中的并发内容。

好吧,事实是这种项目(通用对象池)并没有受到太大的关注,因为现在很少需要它们(对象创建很便宜)。这可能解释了为什么您看不到它们(实际上,我只知道 Commons Pool)。

话虽这么说,如果泛型是您最关心的问题,您可以修补 Commons Pool,请参阅POOL-83,它附带了一个补丁。

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

它确实有一些已知的错误(四个),但据我所知,它可以工作。关于最后一句话,好吧,如果你认为你可以写出更好的东西,如果你有时间,为什么不直接写呢?

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

你没有无限数量的选择。任何一个

  1. 找到可以满足您所有需求的东西(我不知道这样的库,这并不意味着没有)。
  2. 如果您找不到开箱即用的解决方案,请扩展现有解决方案。
  3. 推出自己的解决方案。
于 2010-09-07T10:18:41.203 回答
8

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

  1. 泛型接口- 公共池最明显的问题是它的预泛型接口。有很多方法可以解决这个问题。你可以
    1. 进行铸造;
    2. 实现一个并行接口,为您进行转换;或者
    3. 使用Pascal 确定的补丁
  2. 来自最近的 java 的并发东西- 这是一个你不应该关心的实现细节。如果并发是正确的,那么如何实现正确性并不重要。或者,使用较新的东西但并发错误的池实现仍然是一个糟糕的候选者。
  3. 丑陋的代码- 你应该使用它,而不是嫁给它。
  4. 自定义活性验证- 实现validateObject以测试对象的活性。死物将被销毁。您还可以实现一个Cron任务来定期借用和归还对象 - 强制及时消除死对象。
于 2010-09-11T08:21:17.077 回答
7

在不知道您需要什么功能的情况下很难做出推荐。

如果池中的对象数量是固定的,您可以使用@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);
             }
           });
于 2010-09-11T15:41:00.667 回答
3

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

http://www.kbop.org

于 2013-04-21T17:51:24.827 回答
2

这似乎和你的问题有关,也许你真的应该考虑自己写一个对象池。这个基本的 Java 对象池可以工作吗?.

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

然而,实例池对于自定义“后期构建”缓慢的对象仍然很有趣。在某些情况下,您想在对象创建后注入一些依赖项,读取一些配置等。这可能很慢,并且不必一遍又一遍地执行。在这种情况下,对象池将提高整体性能。

Adam Bien——对象池仍然有用——出于完全不同的原因

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

于 2010-09-10T14:01:06.247 回答
2

另一个池(yapool)包含一个通用池实现,可以选择通过侦听器对池事件进行操作(示例)。这为自定义池行为、添加功能和诊断池资源使用情况提供了很大的灵活性。或者,您还可以扩展池实现以添加您自己想要的行为(示例)。这应该相对简单,因为池实现已经相互扩展(基本 --> 绑定 --> 修剪)。

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

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

于 2013-12-08T15:33:52.593 回答
1

http://code.google.com/p/spf4j/中有一个对象池实现, 我发现它比 apache commons 中的实现更好。代码没那么难看,而且性能更好……

于 2013-03-16T11:50:36.867 回答
0

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

于 2010-09-13T08:50:01.873 回答
-4

池化是传统方式,缓存是现代方式。那里有许多现代的缓存实现。

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

我的观点是,我们可以使用缓存库来池化我们的对象,但不能反过来。只是不要忘记在我们从缓存中获取对象后重新初始化它。那么,如果您只需使用一种动物就可以实现所有目标,为什么还要使用两种不同的动物(缓存和池)呢?

于 2010-09-08T03:49:09.593 回答