首页  

ConcurrentHashMap读操作为什么不需要加锁     所属分类 java 浏览量 268
java8



public V get(Object key) {
    Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek;
    // h>=0
    int h = spread(key.hashCode()); 
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (e = tabAt(tab, (n - 1) & h)) != null) {
        //读取首节点的Node元素
        if ((eh = e.hash) == h) { 
            //如果该节点就是首节点就返回
            if ((ek = e.key) == key || (ek != null && key.equals(ek)))
                return e.val;
        }
        // hash值具体含义 
        //eh=-1,说明该节点是一个ForwardingNode,正在迁移,调用ForwardingNode的find方法去nextTable里找
        //eh=-2,说明该节点是一个TreeBin,调用TreeBin的find方法遍历红黑树 
        //eh>=0,说明该节点下挂的是一个链表,直接遍历该链表即可
        
        // ForwardingNode 和  TreeBin 都可以调用 find 方法
        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;
}


桶定位 tabAt  和  Node  定义 




  /**
     * The array of bins. Lazily initialized upon first insertion.
     * Size is always a power of two. Accessed directly by iterators.
     */
    transient volatile Node<K,V>[] table;

    /**
     * The next table to use; non-null only while resizing.
     */
    private transient volatile Node<K,V>[] nextTable;

static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) {
        return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
}

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


Unsafe getObjectVolatile   
hash 和 key   不可变 ,final   保证可见性
val 和 next   volatile  保证可见性
table数组  volatile  保证引用可见性
volatile + final  保证可见性

上一篇     下一篇
分布式限流方案

lua函数使用说明

jvm相关知识点

java里的协程

一致性算法raft要点

消息队列知识点