jdk1.7 HashMap Fatal error: lista circular

HashMap jdk1.7 en el "error grave": lista circular

configuración jdk1.7 HashMap en la figura.

jdk1.7 es una lista enlazada estructura array +

versiones jdk1.7 existen dos problemas principales

  1. El caso resultará en la cadena de ciclo primera interpolación

  2. La lista es demasiado larga, que dará lugar a la investigación eficacia reducida

versión jdk1.8 optimizado para jdk1.8

  1. Tail utilizando interpolación, la eliminación se produce lista circular
  2. Después de la lista es demasiado larga, en un árbol rojo-negro, mejorar la eficiencia de la consulta

Me refiero específicamente a otro artículo de blog que realmente saben los fabricantes se enfrentan a preguntas: HashMap que?

Producir lista circular

Multithreading Mientras tanto put, si al mismo tiempo llamando a la resizeoperación podría conducir a la lista circular se genera, con lo que el tiempo para volver, será un bucle sin fin. La siguiente detalle la forma circular de forma de lista.

la función de cambio de tamaño

función de expansión Array, la función principal es la de crear una nueva matriz después de la expansión, y llama a la transferfunción migrará los viejos elementos de la matriz a una nueva matriz

void resize(int newCapacity)
{
    Entry[] oldTable = table;
    int oldCapacity = oldTable.length;
    ......
    //创建一个新的Hash Table
    Entry[] newTable = new Entry[newCapacity];
    //将Old Hash Table上的数据迁移到New Hash Table上
    transfer(newTable);
    table = newTable;
    threshold = (int)(newCapacity * loadFactor);
}

función de transferencia

lógica de transferencia es realmente simple, que atraviesa la matriz de edad, el elemento de la matriz por el viejo interpolación cabecera manera, la posición correspondiente a migrar a las nuevas mentiras de problemas en una matriz de interpolación cabeza .

void transfer(Entry[] newTable)
{
    //src旧数组
    Entry[] src = table;
    int newCapacity = newTable.length;
 
    for (int j = 0; j < src.length; j++) {
        Entry<K,V> e = src[j];
        if (e != null) {
            src[j] = null;
            do {
                Entry<K,V> next = e.next; 
                int i = indexFor(e.hash, newCapacity);
                e.next = newTable[i];
                newTable[i] = e;
                e = next;
            } while (e != null);//由于是链表,所以有个循环过程
        }
    }
}

static int indexFor(int h, int length){
    return h&(length-1);
}

He aquí un ejemplo de práctica

//下面详细解释需要用到这部分代码,所以先标号,将一下代码分为五个步骤
do {
	1、Entry<K,V> next = e.next; 
	2int i = indexFor(e.hash, newCapacity);
	3、e.next = newTab[i];
	4、newTable[i] = e;
	5、e= next;
} while(e != null)
  • empezar H una s h METRO una pag HashMap capacidad se establece en 2, se carga el valor de umbral 2 * 0.75 = 1 2 * 0,75 = 1

  • hilo T 2 T_2 e hilo T 1 T_1 Mientras tanto insertar elementos, ya que el valor umbral es 1, por lo que la necesidad de llamar a resizela función, la operación para la expansión

  • hilo T 1 T_1 En primer lugar el bloqueo del código Entry<K,V> next = e.next;, después de hilo T 2 T_2 Después de ejecutar expansión de las operaciones

  • después de hilo T 1 T_1 Despertar, continuar, después de la finalización de un ciclo

    empezar mi 3 e \ rightarrow3 , norte mi X t 7 junto \ rightarrow7 , la aplicación del código siguiente, mi 7 e \ rightarrow 7 , norte mi X t 3 junto \ rightarrow3

    2int i = indexFor(e.hash, newCapacity);
    3、e.next = newTab[i];
    4、newTable[i] = e;
    5、e= next;
    1、Entry<K,V> next = e.next; 
    

  • hilo T 1 T_1 Después de la implantación del segundo ciclo

    empezar mi 7 e \ rightarrow 7 , norte mi X t 3 junto \ rightarrow 3 , se ejecuta el código siguiente, $ e \ rightarrow3 $, norte mi X t norte en l l junto \ rightarrow nula

    2int i = indexFor(e.hash, newCapacity);
    3、e.next = newTab[i];
    4、newTable[i] = e;
    5、e= next;
    1、Entry<K,V> next = e.next; 
    

  • Después de la tercera ejecución del ciclo hilo T1, formando un bucle sin fin

    empezar mi 3 e \ rightarrow 3 , norte mi X t norte en l l junto \ rightarrow nula , el código siguiente, mi norte en l l e \ rightarrow nula

    2int i = indexFor(e.hash, newCapacity);
    3、e.next = newTab[i];
    4、newTable[i] = e;
    5、e= next;
    1、Entry<K,V> next = e.next; 
    

Si se ejecuta get (11), 11% 4 = 3, en un bucle infinito

referencias

JDK1.7 HashMap conducen a lista circular

Publicados 184 artículos originales · ganado elogios 220 · Vistas de 140.000 +

Supongo que te gusta

Origin blog.csdn.net/zycxnanwang/article/details/105415550
Recomendado
Clasificación