JAVA

ConcurrentHashMap 1.8 较 1.7 的改变

2021-05-11  本文已影响0人  交藤

HashTable -> ConcurrentHashMap 1.7 -> ConcurrentHashMap 1.8

这个过程本质上是优化锁的使用,包括锁粒度细化、CAS

  1. 锁粒度细化,方法级别互斥锁 -> 对哈希表分段后加锁 -> 对链表表头对象加锁
  // HashTable
  public synchronized V put(K key, V value) {...}
  
  
  // ConcurrentHashMap JDK 1.7
  static final class Segment<K,V> extends ReentrantLock implements Serializable {...} // 意味着 Segment 本身即为可重入锁,因此对分段对象的访问自带锁功能
  
  
  // ConcurrentHashMap JDK 1.8
  Node<K,V> f;
  f = tabAt(tab, i = (n - 1);       // 取得链表表头/红黑树引用
  synchronized (f) {                // 加锁
    ...
  }
  1. 使用 CAS 乐观锁
          // ConcurrentHashMap JDK 1.7
           if ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u))
                == null) { // recheck
                Segment<K,V> s = new Segment<K,V>(lf, threshold, tab);
                while ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u))
                       == null) {
                    // 初始化设置分段数组
                    if (UNSAFE.compareAndSwapObject(ss, u, null, seg = s))
                        break;
                }
            }
            
            // ConcurrentHashMap JDK 1.8
            // 链表为空时,设置初始节点
            if (casTabAt(tab, i, null,new Node<K,V>(hash, key, value, null)))  
上一篇下一篇

猜你喜欢

热点阅读