当前位置: 首页 > 知识库问答 >
问题:

当对同一段提出读和写请求时,ConcurrentHashMap如何工作?

冀弘济
2023-03-14

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

>

  • 对段10输入读请求,对同一段10输入写请求。当一个请求正在读取时,一个写请求尝试修改它。写请求如何知道它必须等到读取完成?ConcurrentHashMap中有两个单独的锁,一个用于读,一个用于写,还是只有一个锁?write是否也必须为write获取读锁,这就是write等待的原因?如果只有一个锁,同时读取如何工作?

    两个请求%1和%2进入同一段%2。请求%1获取段%1上的锁,请求是否必须等待到%2完成读取?

  • 共有1个答案

    孙渝
    2023-03-14

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

    在空bin中插入(通过+[]=+或其变体)第一个节点只需将其封装到bin中即可。这是大多数键/散列分布下put操作最常见的情况。其他更新操作(insert、delete和replace)需要锁。我们不想浪费将不同的锁对象与每个bin关联所需的空间,因此使用bin列表的第一个节点作为锁。阻止对这些锁的支持依赖于+util::cheaplockable。但是,我们还需要一个try_lock结构,因此我们通过使用节点哈希字段的位来覆盖这些结构来进行锁控制(参见上文),因此通常只使用内置监视器来使用cheap_wait/cheap_broadcast结构进行阻塞和信令。请参阅+node#try_await_lock+。对这些锁的锁定支持依赖于内置的“同步”监视器。这意味着

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

    对于读取值,没有阻塞

    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;
        }
    
     类似资料:
    • 如果是的话,有谁能向我解释如何做到这一点?

    • 编辑:我在代码中添加了一个条件语句来检查curl_error($ch)的结果。它显然没有返回错误。我还添加了一个curl_setop来将CURLOPT_POST设置为true。 我正在尝试使用PHP和cURL连接到API,并回调一个JSON响应以显示在页面上。然而,虽然我最初的访问令牌请求通过一个简单的GET请求成功,但我随后的POST请求并没有返回任何数据。 我已经能够使用Postman(下面的

    • 我需要帮助如何在我的服务器(index.js)中正确编写GET和POST请求,以及如何在应用程序中正确编写fetch。js。 我阅读了Stackoverflow上的线程,并搜索了有关如何编写请求和获取的信息,但我发现如何将示例添加到自己的代码中非常困难。我已经尝试了三个星期不同的解决方案,但都一事无成。所以,请帮忙。我觉得这应该没那么难,但出于某种原因确实如此。除了这里,我没有人需要帮助。 我正在

    • 这是POST请求的实际图像[使用Android改造上传图像,如何使用改造进行多部分请求][2] 我使用翻新发送了多个图像文件和字符串数据,但在服务器端缺少字符串数据 我的保存注册 API

    • 这是在收到以db为单位的帖子列表后发送带有每个帖子链接数据的POST请求的代码。 在使用每个链接请求帖子后,从回复中提取playerCount并将其更新到每个帖子。 我在这段代码中使用Resttemplate,但有一个问题需要花费太长时间。 所以我想把这个代码改为一次发送一个请求,并在所有请求完成后更新每个帖子。 我怎样才能把这个代码转换成我想要的? 我将使用此代码作为计划任务。

    • 问题内容: 我正在尝试通过COM端口发送AT命令,但只重新发送了相同的命令。 日志: 16:19:21.910 [main]调试SerialConnections.M234Serial-创建实例。 16:19:21.974 [main]调试SerialConnections.M234Serial-发送请求:AT ^ SCFG? 16:19:23.976 [EventThread COM55]调试S