简体   繁体   English

当读取和写入请求来自同一段时,ConcurrentHashMap 如何工作?

[英]How does ConcurrentHashMap work when read and write request come for the same segment?

I am trying to understand how locks work in ConcurrentHashMap.我试图了解锁在 ConcurrentHashMap 中是如何工作的。 My understanding is that in ConcurrentHashMap there are segments and a write requests acquires a lock on a particular segment while there can be simultaneous reads on other segments.我的理解是,在 ConcurrentHashMap 中有段,写入请求在特定段上获取锁,而在其他段上可以同时读取。 But say,但是说,

  1. A read request comes in for segment 10, and a write request comes in for the same segment 10. While a request is reading, a write request tries to modify it.读请求进入第 10 段,而写请求进入同一段 10。当请求正在读取时,写请求会尝试修改它。 How does the write request know it has to wait until a read is finished?写入请求如何知道它必须等到读取完成? Are there two separate locks one for read and one write lock in ConcurrentHashMap or just one lock? ConcurrentHashMap 中是否有两个单独的锁,一个用于读取锁,一个用于写入锁,还是只有一个锁? Does write have to acquire a read lock too for writing and that's the reason why write waits?写入是否也必须获得读取锁才能写入,这就是写入等待的原因? If there is only one lock how does simultaneous read work?如果只有一个锁,同时读取如何工作?

  2. Two requests 1 and 2 come in for the same segment 2. Request 1 acquires the lock on segment 1, does the request have to wait until 2 has finished reading?两个请求 1 和 2 进入同一个段 2。请求 1 获得了段 1 上的锁,请求必须等到 2 完成读取吗?

The best way to understand ConcurrentHashMap, is by understanding synchronization in java in reviewing the source code.理解 ConcurrentHashMap 的最佳方法是在查看源代码时理解 java 中的同步。 From the Source code http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/concurrent/ConcurrentHashMap.java来自源代码http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/concurrent/ConcurrentHashMap.Z93F725A07423FE1C8849F448B33D21F

Insertion (via +[]=+ or its variants) of the first node in an empty bin is performed by just CASing it to the bin.将第一个节点插入(通过 +[]=+ 或其变体)到空 bin 中,只需将其 CASing 到 bin 中即可。 This is by far the most common case for put operations under most key/hash distributions.这是迄今为止在大多数键/哈希分布下进行 put 操作的最常见情况。 Other update operations (insert, delete, and replace) require locks.其他更新操作(插入、删除和替换)需要锁定。 We do not want to waste the space required to associate a distinct lock object with each bin, so instead use the first node of a bin list itself as a lock.我们不想浪费将不同锁 object 与每个 bin 关联所需的空间,因此请使用 bin 列表的第一个节点本身作为锁。 Blocking support for these locks relies + Util::CheapLockable .对这些锁的阻塞支持依赖于 + Util::CheapLockable However, we also need a try_lock construction, so we overlay these by using bits of the Node hash field for lock control (see above), and so normally use builtin monitors only for blocking and signalling using cheap_wait/cheap_broadcast constructions.然而,我们还需要一个 try_lock 结构,因此我们通过使用 Node hash 字段的位来进行锁定控制(见上文),因此通常使用内置监视器仅用于阻塞和使用cheap_wait/cheap_broadcast结构发出信号。 See +Node#try_await_lock+.请参阅 +Node#try_await_lock+。 Locking support for these locks relies on builtin "synchronized" monitors.对这些锁的锁定支持依赖于内置的“同步”监视器。 which mean也就是说

Which basically means every Insert/Update/Delete operation on ConcurrentHashMap will blocked until the operation is finished这基本上意味着 ConcurrentHashMap 上的每个插入/更新/删除操作都将被阻塞,直到操作完成

for read value there is no blocking对于读取值,没有阻塞

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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM