首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当同一段的读和写请求来时,ConcurrentHashMap是如何工作的?

当同一段的读和写请求来时,ConcurrentHashMap是如何工作的?
EN

Stack Overflow用户
提问于 2021-02-17 13:15:16
回答 1查看 133关注 0票数 2

我正试图了解ConcurrentHashMap中的锁是如何工作的。我的理解是,在ConcurrentHashMap中有段,写请求获取特定段的锁,而在其他段上可以同时读取。但是说,

  1. 读取请求是针对段10的,而写请求是针对同一段10的。当请求正在读取时,写请求试图修改它。写入请求如何知道它必须等待读取完成?在ConcurrentHashMap中有两个单独的锁,一个用于读锁和一个写锁,还是只有一个锁?写是否也需要获得一个读锁来写,这就是为什么写等待?如果只有一个锁,如何同时读取?

  1. 2请求1和2进入同一段2。请求1获得段1上的锁,请求必须等到2完成读取吗?
EN

回答 1

Stack Overflow用户

发布于 2021-02-17 14:07:15

理解ConcurrentHashMap的最佳方法是在查看源代码时理解java中的同步。来自源代码http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/concurrent/ConcurrentHashMap.java

对空bin中的第一个节点执行

插入(通过+[]=+或其变体),只需将其插入到bin。到目前为止,这是在大多数key/hash发行版下进行put操作的最常见情况。其他更新操作(插入、删除和替换)需要锁。我们不想浪费将一个单独的锁对象与每个bin相关联所需的空间,所以使用bin列表本身的第一个节点作为锁。对这些锁的阻塞支持依赖于+Util::CheapLockable。但是,我们还需要一个try_lock结构,因此我们使用节点哈希字段的位来控制锁(参见上文),因此通常只使用内置监视器来使用cheap_wait/cheap_broadcast结构来阻塞和发送信令。见+Node#try_await_lock+。对这些锁的锁定支持依赖于内置的“同步”监视器。这意味着

这基本上意味着ConcurrentHashMap上的每个插入/更新/删除操作都会被阻塞,直到操作完成为止。

对于读取值,不存在阻塞。

代码语言:javascript
复制
public V get(Object key) {

        Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek;

        int h = spread(key.hashCode());

        if ((tab = table) != null && (n = tab.length) > 0 &&

            (e = tabAt(tab, (n - 1) & h)) != null) {

            if ((eh = e.hash) == h) {

                if ((ek = e.key) == key || (ek != null && key.equals(ek)))

                    return e.val;

            }

            else if (eh < 0)

                return (p = e.find(h, key)) != null ? p.val : null;

            while ((e = e.next) != null) {

                if (e.hash == h &&

                    ((ek = e.key) == key || (ek != null && key.equals(ek))))

                    return e.val;

            }

        }

        return null;
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66242664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档