ConcurrentHashMap computeIfAbsent [英] ConcurrentHashMap computeIfAbsent

查看:184
本文介绍了ConcurrentHashMap computeIfAbsent的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java 8中引入了一个新的computeIfAbsent API。
ConcurrentHashMap的强制执行状态:

There is a new computeIfAbsent API introduced in Java 8. The javadocs for ConcurrentHashMap's impelementation of it state:


如果指定的键尚未与值关联,则尝试使用给定的映射函数计算其值,并将其输入此映射,除非为null。整个方法调用是以原子方式执行的,因此每个键最多应用一次该函数。其他线程在此映射上的某些尝试更新操作可能会在计算进行时被阻止,因此计算应该简短,并且不得尝试更新此映射的任何其他映射。

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.

那么,在密钥已经存在且计算不需要的情况下,它对锁定此实现有何看法?整个方法computeIfAbsent如文档中所述是同步的,即使不需要计算,或只是映射函数调用是同步的,以防止调用函数两次?

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 syncronized to prevent calling the function twice?

推荐答案

ConcurrentHashMap <的实现/ a>非常复杂,因为它专门设计为允许并发可读性,同时最小化更新争用。在非常高的抽象级别,它被组织为一个分段的哈希表。所有读取操作都不需要锁定,并且(引用javadoc)没有任何支持以阻止所有访问的方式锁定整个表。为了实现这一点,内部设计非常复杂(但仍然很优雅),节点中保存了键值映射,可以以各种方式(例如列表或平衡树)进行排列,以便利用细粒度锁。如果您对实现细节感兴趣,还可以查看源代码

The implementation of ConcurrentHashMap is quite complex, as it is specifically designed to allow concurrent readability while minimizing update contention. At a very high level of abstraction, it is organized as a bucketed hash table. All read operations do not require locking, and (quoting the javadoc) "there is not any support for locking the entire table in a way that prevents all access". To accomplish this, the internal design is highly sophisticated (but still elegant), with key-value mappings held in nodes which can be arranged in various ways (such as lists or balanced trees) in order to take advantage of fine grained locks. If you're interested in implementation details you can also have a look at the 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?

可以合理地认为,与任何读操作一样,不需要锁定来检查密钥是否已经存在且映射函数不需要执行。

It is reasonable to think that, as with any read operation, no locking is required to check if the key already exists and the mapping function does not need to be executed.


整个方法computeIfAbsent如docs
中所述同步,即使不需要计算或只是映射函数调用是
同步以防止调用该函数两次?

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?

不,该方法不是同步在t锁定的问题,但从调用者的角度来看,它是以原子方式执行的(即映射函数最多应用一次)。如果未找到密钥,则必须使用映射函数计算的值执行更新操作,并且在调用该函数时涉及某种锁定。可以合理地认为这种锁定是非常细粒度的,并且只涉及表的一小部分(以及必须存储密钥的特定数据结构),这就是为什么(引用javadoc,强调我的)其他线程某些尝试更新操作可能在计算过程中被阻止。

No, the method is not synchronized in terms of locking, but from the point of view of the caller it is executed atomically (i.e. the mapping function is applied at most once). If the key is not found, an update operation must be performed using the value computed by the mapping function and some kind of locking is involved while that function is invoked. It is reasonable to think that such locking is very fine-grained and only involves a very small portion of the table (well, the specific data structure where the key has to be stored) and this is why (quoting the javadoc, emphasis mine) "some attempted update operations by other threads may be blocked while computation is in progress".

这篇关于ConcurrentHashMap computeIfAbsent的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆