映射允许putIfAbsent而不创建密钥已存在时的值

时间:2012-04-15 02:45:25

标签: java concurrency map garbage

我想使用一个等同于ConcurrentMap的地图(我希望相当于 putIfAbsent 方法),但这不会强迫我事先创建对象。

例如,当我这样做时:

m.putIfAbsent( key, new CyclingArray() );

我可能最终无需创建新的 CyclingArray (无论是什么)对象。

当然我意识到我可以锁定整个地图,但这会打败ConcurrentMap的整个点。

以下工作可以概念化吗?

   m.putIfAbsent( key, new Callback<CyclingArray>() {
     @Override
     public CyclingArray provide() {
       return new CyclingArray();  // only called if the key wasn't already present
     }         
   }

您知道任何提供地图的图书馆:

  1. 提供类似ConcurrentMap提供的“接口”,包括putIfAbsent方法。
  2. 只锁定我们要使用的细分(例如ConcurrentHashMap实现)
  3. 允许选择性地创建值,当且仅当密钥不存在时,才能避免无用的垃圾生成。
  4. 不会强迫我首先使用 containsKey 然后使用 putIfAbsent ,因为这也会以某种方式违背 putIfAbsent 的目的。< / LI>

    请注意,我询问上述示例是否可以使用ConcurrentMap(它不能是AFAIK)完成。

    我在考虑使用回调版本扩展ConcurrentHashMap并重载 putIfAbsent 但遗憾的是ConcurrentHashMap内部使用了最终的 Segment 类。

    在重新发明轮子之前,我想知道是否有任何地图已经提供了类似的功能。

1 个答案:

答案 0 :(得分:5)

这是您正在寻找的常见用例,称为memoization。我会看MapMaker

您可以创建一个computingMap并将创建函数放在那里:

 ConcurrentMap<Key, CyclingArray> graphs = new MapMaker()
       .concurrencyLevel(32)
       .makeComputingMap(
           new Function<Key, CyclingArray>() {
                public CyclingArray  apply(Key key) {
                    return new CyclingArray();  // only called if the key wasn't already    
                }              
           });

此处Function仅在Key不存在时才会被调用

而且我确实知道Java中的未来计划有一个computeMap类型接口将带有标准Java,不幸的是,此时你将不得不委托google-collections。