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

问题描述

Java 8中引入了一个新的computeIfAbsent API。
状态:

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

那么,在密钥已经存在且计算不需要的情况下,它对锁定此实现有何看法?整个方法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?

推荐答案

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.

尝试回答您的问题:

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

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.

不,该方法不是同步在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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 21:33
查看更多