2

我想使用一个相当于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的目的。

请注意,我不是在问上面的例子是否可以用 a 完成ConcurrentMap(它不能 AFAIK)。

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

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

4

1 回答 1

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 的未来计划有一个计算地图类型接口将随标准 Java 一起提供,不幸的是,此时您将不得不委托给 google-collections。

于 2012-04-15T03:59:01.510 回答