- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我发布了一个答案 here其中演示使用 ConcurrentMap
的 putIfAbsent
方法的代码读取:
ConcurrentMap<String, AtomicLong> map = new ConcurrentHashMap<String, AtomicLong> ();
public long addTo(String key, long value) {
// The final value it became.
long result = value;
// Make a new one to put in the map.
AtomicLong newValue = new AtomicLong(value);
// Insert my new one or get me the old one.
AtomicLong oldValue = map.putIfAbsent(key, newValue);
// Was it already there? Note the deliberate use of '!='.
if ( oldValue != newValue ) {
// Update it.
result = oldValue.addAndGet(value);
}
return result;
}
这种方法的主要缺点是您必须创建一个新对象以放入 map 中,无论它是否会被使用。如果物体很重,这会产生重大影响。
我想到这将是一个使用 Lambdas 的机会。我还没有下载 Java 8,或者在它正式发布(公司政策)之前我是否可以下载,所以我无法测试它,但这样的东西是否有效?
public long addTo(String key, long value) {
return map.putIfAbsent( key, () -> new AtomicLong(0) ).addAndGet(value);
}
我希望使用 lambda 来延迟对 new AtomicLong(0)
的评估,直到它实际确定应该创建它,因为它不存在于映射中。
如您所见,这更加简洁和实用。
基本上我想我的问题是:
最佳答案
2015-08-01 更新
下面描述的computeIfAbsent
方法确实是added to Java SE 8 .语义似乎非常接近预发布版本。
此外,computeIfAbsent
以及一大堆新的默认方法已添加到 Map
接口(interface)中。当然, map 一般不支持原子更新,但新方法为 API 增加了相当大的便利。
您尝试做的事情很合理,但不幸的是它不适用于当前版本的 ConcurrentMap
。然而,改进正在进行中。新版本的并发库包括 ConcurrentHashMapV8
,其中包含一个新方法 computeIfAbsent
。这几乎可以让您完全按照自己的意愿行事。使用这种新方法,您的示例可以重写如下:
public long addTo(String key, long value) {
return map.computeIfAbsent( key, () -> new AtomicLong(0) ).addAndGet(value);
}
有关 ConcurrentHashMapV8
的更多信息,请参阅 Doug Lea 的 initial announcement thread在并发兴趣邮件列表上。线程中的几条消息是a followup message这显示了一个与您正在尝试做的非常相似的示例。 (但是请注意旧的 lambda 语法。毕竟该消息是从 2011 年 8 月开始的。)这里是 recent javadoc对于 ConcurrentHashMapV8
。
这项工作旨在集成到 Java 8 中,但据我所知还没有。此外,这仍在进行中,名称和规范可能会发生变化等。
关于java - Lambda 和 putIfAbsent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14876967/
是否可以使用 putIfAbsent 或其任何等效项(如短路运算符)。 myConcurrentMap.putIfAbsent(key,calculatedValue) 我希望如果已经存在计算值,则不
我正在使用 Cassandra 并使用 Datastax Java 驱动程序。我正在尝试通过缓存来重用准备好的语句。 private static final ConcurrentHashMap
我想在我的应用程序中使用 ConcurrentSkipListMap,但不太确定如何处理它。查看源代码,我没有找到任何 Lock 获取的 synchronized 语句。 Documentation也
我有这个 map 定义: TreeMap > 它可能包含数百万个条目,我还需要一个“自然顺序”(这就是我选择 TreeMap 的原因,尽管如果需要我可以编写一个比较器)。 所以,为了向 map 添加元
public static void main(String args[]) throws Exception { ConcurrentHashMap dps = new C
我在使用 putIfAbsent 时遇到问题,第二个线程将在第一个线程完成使用 pk 更新值之前尝试访问该值。 示例代码。 public Object getLookupValue(final Cl
我有一个 ConcurrentHashMap 和一个将字符串放入映射中的方法,然后我根据插入的值在同步块(synchronized block)中执行一些操作。 putIfAbsent 返回与指定键关
我想使用一个等同于 ConcurrentMap 的 map (我想要等同于 putIfAbsent 方法)但这不会强制我创建事先反对。 例如当我这样做时: m.putIfAbsent( key, ne
ConcurrentMap 指定putIfAbsent() 的返回值为: the previous value associated with the specified key, or null i
我是 Java 世界的新手,正在探索 concurrentHashMap,在探索 concurrentHashMap API 时,我发现了 putifAbsent()方法 public V putIf
我发布了一个答案 here其中演示使用 ConcurrentMap 的 putIfAbsent 方法的代码读取: ConcurrentMap map = new ConcurrentHashMap (
在his talk about Effective Java在 54:15 Joshua Bloch 建议在 putIfAbsent 之前使用 get 以提高性能和并发性。这让我想到了为什么这个优化还
查看接口(interface)Map中默认方法putIfAbsent的实现, default V putIfAbsent(K key, V value) { V v = get(key);
在 Java 中,我想向常规映射添加一个 getOrAdd 方法,就像在 ConcurrentHashMap 上添加 putIfAbsent 一样。 此外,对于某个键,我想存储一个项目列表。这是我的尝
我有一种情况,调用者希望根据当前实例(标识符)获取 bean 的对象。现在,如果当前实例存在 bean 对象,则不应再次创建它。所以有两种方法(我认为)可以做到这一点 - 1. Using putIf
我有一个 java.util.concurrent.ConcurrentHashMap,如果它不存在,我想放置它,但如果存在,我也想将其删除。像这样的东西: ConcurrentHashMap map
我有一个像这样的 ConcurrentMaps 的 ConcurrentMap... ConcurrentMap> mapsMap = new ConcurrentHashMap<>(); 现在在某些
从昨天开始,我一直在阅读并发性知识,我不太了解...但是有些事情开始变得清晰... 我理解为什么双重检查锁定不安全(我想知道这种罕见情况发生的概率是多少)但是 volatile 修复了 1.5 + 中
简介 这是关于 infinispan 缓存的,但我认为这是一个足够通用的问题。 在我的 infinispan 缓存中,我使用 putIfAbsent 方法将项目输入到缓存中,并使用 remove 方法
我在 tomcat 下部署了一个 java web 应用程序,突然 API 的响应时间变慢,如快照所示(抱歉,由于缺乏声誉,我无法发布图像。)。重启tomcat后即可恢复正常。 唯一引起我注意的可疑代
我是一名优秀的程序员,十分优秀!