- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
Java 8 中引入了一个新的 computeIfAbsent API。ConcurrentHashMap's impelementation of it 的 javadocs状态:
If the specified key is not already associated with a value, attempts to compute its value using the given mapping function and enters it into this map unless null. The entire method invocation is performed atomically, so the function is applied at most once per key. Some attempted update operations on this map by other threads may be blocked while computation is in progress, so the computation should be short and simple, and must not attempt to update any other mappings of this map.
那么,在 key 已经存在且不需要计算的情况下,锁定此实现有何意义?整个方法 computeIfAbsent 是否如文档中所述同步,即使不需要计算或仅同步映射函数调用以防止调用函数两次?
最佳答案
执行ConcurrentHashMap非常复杂,因为它专门设计用于允许并发可读性,同时最大限度地减少更新争用。在一个非常高的抽象层次上,它被组织为一个分桶哈希表。所有读取操作都不需要锁定,并且(引用 javadoc)“不支持以阻止所有访问的方式锁定整个表”。为了实现这一点,内部设计非常复杂(但仍然优雅),键值映射保存在节点中,节点可以以各种方式(例如列表或平衡树)排列,以利用细粒度锁。如果您对实现细节感兴趣,您还可以查看 source code .
尝试回答您的问题:
So, what does it say about locking of this implementation in case when the the key already exists and the computation is unneeded?
可以合理地认为,与任何读取操作一样,不需要锁定来检查键是否已经存在并且不需要执行映射函数。
Is the whole method computeIfAbsent synchronized as stated in docs even if no calculation is needed or just the mapping function call is synchronized to prevent calling the function twice?
不,该方法在锁定方面不是同步,但从调用者的角度来看,它是原子执行的(即映射函数最多应用一次)。如果未找到键,则必须使用映射函数计算的值执行更新操作,并且在调用该函数时涉及某种锁定。可以合理地认为这种锁定是非常细粒度的并且只涉及表的很小一部分(嗯,必须存储 key 的特定数据结构)这就是原因(引用 javadoc,强调我的) “一些 其他线程尝试的更新操作可能在计算过程中被阻止”。
关于java - ConcurrentHashMap computeIfAbsent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26481796/
我最初构造了一系列嵌套的 ConcurrentHashMaps private final ConcurrentHashMap allInOne = new ConcurrentHashMap
我正在尝试使用 ConcurrentHashMap 初始化 ConcurrentHashMap private final ConcurrentHashMap > myMulitiConcurrent
为了提高工作效率,我尝试将数据保存在一个动态容器中。 我在 class 中初始化它与 private final ConcurrentHashMap allInOne = new Concur
我正在创建基于 Socket 的服务器-客户端预订服务,并且遇到有关将由多个线程访问的类的问题,是否需要扩展 ConcurrentHashMap 或创建变量 ConcurrentHashMap 是否足
从 Javadoc 我知道 ConcurrentHashMap.replace 是原子的,但是 ConcurrentHashMap.put 呢?我看到它们在源代码中的实现方式不同,但我无法弄清楚它们的
是 ConcurrentHashMap.get() 保证看到以前的ConcurrentHashMap.put()通过不同的线程?我的期望是,阅读 JavaDocs 似乎表明了这一点,但我 99% 确信
使用 ConcurrentHashMap,我发现 computeIfAbsent 比 putIfAbsent 慢两倍。这里是简单的测试: import java.util.ArrayList; imp
我有一个以下格式的 ConcurrentHashMap: ConcurrentHashMap> 现在在此 map 中,我想删除数组列表中的特定值。任何人都可以指导这一点。 编辑1:我有一张 map >
为什么 ConcurrentHashMap.Segment 和 ConcurrentHashMap.HashEntry 类是静态的?为什么要这样设计? 最佳答案 基本上所有不需要使用其封闭类属性的内部
在 ConcurrentHashMap 中通过键递增并发计数器时,使用常规 Int 作为值是否安全,还是我们必须使用 AtomicInteger?例如考虑以下两个实现 ConcurrentHashMa
我对java中的并发数据结构有疑问,特别是: 1) ConcurrentHashMap 2) HashMap 3) ConcurrentHashMap 如果我理解正确的话: 1) 读/写是线程安全的,
我正在尝试查看实际的 Java 文档,描述传递给 ConcurrentHashMap.computeIfAbsent 和 ConcurrentHashMap.computeIfPresent< 时可以
我有一个名为 SerializableL 的接口(interface)由 3 个不同的类实现: 产品 横幅 标签 我开始重构,想用多个方法调用替换多个段落。 public void load(Conc
一 JDK 中的 ConcurrentHashMap 在 JDK 8以前,HashMap 是基于数组 + 链表来实现的。整体上看,HashMap 是一个数组,但每个数组元素又是一张链表。 当向 Has
我想知道当我们在调整大小时尝试读取 ConcurrentHashMap 时可能发生的情况。 我知道在读取期间,第一次尝试总是不同步的。在第二次尝试中,它将尝试获取锁并重试。 但是,如果它在调整大小时发
在一个应用程序中,1 个线程负责不断更新映射,主线程定期读取映射,使用 ConcurrentHashmap 是否足够?或者我应该明确地锁定同步块(synchronized block)中的操作吗?任何
介绍 ConcurrentHashMap 技术是为了解决问题而生的,ConcurrentHashMap 解决了多个线程同时操作一个 HashMap 时,可能出现的内部问题。当多个线程同时操作一
我有一个由多个线程访问的键值映射: private final ConcurrentMap key_vval_map = new ConcurrentHashMap(); 我的自定义 get() 和
谁能告诉我这段代码出了什么问题?我要拔头发了! 如果我使用 HashMap 而不是 ConcurrentHashMap 则没有任何问题。代码使用JDK 5.0编译 public class MapTe
来自 ConcurrentHashMap 的源码 /** 171 * Number of unsynchronized retries in size and containsVal
我是一名优秀的程序员,十分优秀!