写作与程序程序员

学习Java基础知识,打通面试关九~ConcurrentHash

2018-06-03  本文已影响64人  胖琪的升级之路

在上一篇文章中我们说到了Map集合中的一部分内容,还有并发包中的Map并没有说到,现在我们来说下并发包中的Map~ConcurrentHashMap。

Java8之前的ConcurrentHashMap 实现

在前期中ConcurrentHashMap的基本实现思路:

Java8的ConcurrentHashMap实现

在实现上放弃的Segment 的实现,采用了Node +CAS + Synchronized 来保证并发的安全。

/**
     * Initializes table, using the size recorded in sizeCtl.
     */
    private final Node<K,V>[] initTable() {
        Node<K,V>[] tab; int sc;
        while ((tab = table) == null || tab.length == 0) {
                //sizeCtl表示有其他线程正在进行初始化操作,把线程挂起。对于table的初始化工作,只能有一个线程在进行。
            if ((sc = sizeCtl) < 0)
                Thread.yield(); // lost initialization race; just spin
            else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {//利用CAS方法把sizectl的值置为-1 表示本线程正在进行初始化
                try {
                    if ((tab = table) == null || tab.length == 0) {
                        int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
                        @SuppressWarnings("unchecked")
                        Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
                        table = tab = nt;
                        sc = n - (n >>> 2);//相当于0.75*n 设置一个扩容的阈值
                    }
                } finally {
                    sizeCtl = sc;
                }
                break;
            }
        }
        return tab;
    }
  1. 扩容分为了两部分,构建新的nextTable ,容量是原先的两倍,单线程操作。
  2. 进行数据复制到新的nextTable中,这里是多线程操作。
  3. 整体 遍历每个节点,然后复制的过程
上一篇下一篇

猜你喜欢

热点阅读