Java 8 ConcurrentHashMap [英] Java 8 ConcurrentHashMap

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

问题描述

我发现ConcurrentHashMap已经在Java 8中完全重写为更无锁。我浏览了 get()方法的代码,看到没有明确的锁机制:

I've observed that ConcurrentHashMap has been entirely rewritten in Java 8 to be more "lock-free". I've browsed the code of the get() method and see that there is no explicit lock mechanism:

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

问题:

如何从一个线程中看到从其他线程对此hashmap进行的修改,因为代码不在同步伞下(这将强制发生在关系之前)

How it is possible to see from one thread, modifications done to this hashmap from other threads, since the code isn't under a synchronize umbrella (which would enforce a happens-before relation)?

注意:整个ConcurrentHashMap是表的包装器:
瞬态易失性节点< K,V> [] table;

Note: The entire ConcurrentHashMap is a wrapper of a table: transient volatile Node<K,V>[] table;

所以 table 是一个易变的引用数组,而不是对volatile元素数组的引用!这意味着如果有人正在更新此数组中的元素,则修改将不会在其他线程中看到。

So table is a volatile reference to an array, not a reference to an array of volatile elements! Which means that if someone is updating an element inside this array, the modification won't be seen in other threads.

推荐答案

简答



节点#val volatile 在订购前确定您的发生。

Short answer

The Node#val is volatile which establishes your happens before ordering.

synchronized 不是线程安全的要求,它■在工具箱一个工具,使系统线程安全的。你必须考虑一下这个 ConcurrentHashMap 的整套动作来推断线程安全。

synchronized isn't a requirement for thread safety, it's one tool in a toolbox to make a system thread safe. You'll have to consider an entire set of actions on this ConcurrentHashMap to reason about thread safety.

它很有用要知道原来的 ConcurrentHashMap 也是非阻塞的。注意pre-Java 8 CHM get

It's useful to know the original ConcurrentHashMap too is non-blocking. Notice pre-Java 8 CHM get

V get(Object key, int hash) {
    if (count != 0) { // read-volatile
        HashEntry<K,V> e = getFirst(hash);
        while (e != null) {
            if (e.hash == hash && key.equals(e.key)) {
                V v = e.value;
                if (v != null)
                    return v;
                return readValueUnderLock(e); // ignore this
            }
            e = e.next;
        }
    }
    return null;
}

在这种情况下,没有阻止,所以它是如何工作的? HashEntry#值 volatile 。这是线程安全的同步点。

In this case, there is no blocking, so how does it work? The HashEntry#value is volatile. That is the synchronization point for thread safety.

CHM-8的节点类是相同的。

The Node class for CHM-8 is the same.

static class Node<K,V> implements Map.Entry<K,V> {
    final int hash;
    final K key;
    volatile V val;
    volatile Node<K,V> next;

因此,在这种情况下,一个非零的val应确保在关系到之前的行为之前发生投注。

So a non-null val in this case should ensure thee happens-before relationship with respect to actions prior to a put.

这篇关于Java 8 ConcurrentHashMap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆