The closed-loop linked list problem of HashMap in JDK1.7

Problem Description:

  In Jdk1.7, the expansion mechanism of HashMap adopts the "head insertion method", that is, when the element hash reaches the new array slot, it is inserted at the head of the linked list. The reason is: adding elements to the tail, the time complexity is O (n), and head insertion can improve performance.

  Although we know that HashMap is not thread-safe, this way of writing will cause closed-loop linked list problems when concurrently expanding (resize).

Cause Analysis:

  

 void resize(int newCapacity) {
        Entry[] oldTable = table;
        int oldCapacity = oldTable.length;
        if (oldCapacity == MAXIMUM_CAPACITY) {
            threshold = Integer.MAX_VALUE;
            return;
        }

        Entry[] newTable = new Entry[newCapacity];
        transfer(newTable, initHashSeedAsNeeded(newCapacity));
        table = newTable;
        threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1); 
    } 

    / ** 
     * Transfers all entries from current table to newTable. 
     * / 
    Void transfer (Entry [] newTable, boolean rehash) {
         int newCapacity = newTable.length;
         for (Entry <K, V> e: table) {
             while ( null ! = e) {
                 Entry <K, V> next = e.next; // This line of code? is the key code that causes the problem.
                if (rehash) { 
                    e.hash = null == e.key? 0 : hash (e.key); 
                } 
                int i = indexFor(e.hash, newCapacity);
                e.next = newTable[i];
                newTable[i] = e;
                e = next;
            }
        }
    }

 

Guess you like

Origin www.cnblogs.com/akid1994/p/12700068.html