Dan*_*Dan 5 java concurrenthashmap
假设我们有 10 个线程使用不同的键值调用以下代码。提供给computeIfAbsent方法的“Function”参数是否并行运行,或者computeIfAbsent将“锁定”整个表?
Map<String, String> map = new ConcurrentHashMap<>();
map.computeIfAbsent(key, K -> { // long time operation });
Run Code Online (Sandbox Code Playgroud)
有两种方法可以解释这个问题。
第一个是,从理论上讲,该方法的规范ConcurrentHashMap.computeIfAbsent是否保证仅在正在计算的特定键上进行同步?这个问题的答案直接来自该方法的文档:
当计算正在进行时,其他线程对此映射的某些尝试更新操作可能会被阻止,因此计算应该简短且简单,并且不得尝试更新此映射的任何其他映射。
这是不明确的,它是在整个映射上同步还是仅在单个键上同步,但它没有明确承诺在计算 value-if-absent 时可以在其他线程中进行其他键的更新。它表示“某些尝试的更新操作”可能会被阻止,但并没有限制哪些操作或有多少操作被阻止。所以严格的答案是,不,允许一致的实现在整个地图对象上同步,并阻止所有其他更新。
该问题的第二种解释是,实际上,该方法的实现是否仅在单个密钥上同步?这个问题的答案将取决于哪个实现,但将来自该实现的源代码。
Node<K,V> f;
// ...
if(/* ... */) {
// ...
} /* ... */ else if(/* ... */) {
Node<K,V> r = new ReservationNode<K,V>();
synchronized (r) {
// ...
}
// ...
} /* ... */ else {
// ...
synchronized (f) {
// ...
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
所以答案(至少如果您使用此实现)是yes,实际上,该方法在表示单个键/值对的对象(或 )上同步f,r而不是整个映射,因此不应更新其他键计算函数时被阻塞。
| 归档时间: |
|
| 查看次数: |
3317 次 |
| 最近记录: |