"Aprender Ensayo -2" - HashMap no es hilo de seguridad (jdk8 también causa un bucle infinito, sin embargo, la razón de identificar)

HashMap

concepto básico

            HashMap consigue mediante la matriz anterior más lista JDK7 y ha añadido en el jdk8 árbol rojo-negro, la longitud de la cadena 8, cuando se convierte a árbol rojo-negro, la lista se reduce a 6 gotas. Predeterminado capacidad de la matriz de inicialización 16, cada expansión es una potencia de 2, el factor de carga por defecto es 0,75

           Como todos sabemos, es HashMap hilo insegura, insegura de cómo una ley, o para ejecutar el código y ver el efecto, sólo se sienten.



código de prueba HashMap thread-safe

           Código lanzó dos hilos de un total de datos de los mapas almacenados en un total de 100.000.

public class HashMapTestThread {


    static Map<String,String> map = new HashMap<String,String>();


    public static class AddThread implements Runnable{

        int start=0;

        public AddThread(int start){

            this.start = start;

        }

        @Override
        public void run(){
            for (int i = start; i < 100000; i+=2) {
                map.put(Integer.toString(i),Integer.toBinaryString(i));
            }
        }

    }

    public static void main(String[] args) throws Exception{
        Thread t1 = new Thread(new HashMapMultiThread.AddThread(0));
        Thread t2 = new Thread(new HashMapMultiThread.AddThread(1));
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(map.size());
    }


}

Hay tres posibles resultados operativos sustancialmente:

1. Los extremos de los programas normalmente, el resultado es correcto, map.siz () Resultado 100000 (ejecutar varias veces no es un éxito)

2. Los extremos del programa normalmente, el resultado es menor que 100 000 (esto ocurre es alta probabilidad), como se muestra a continuación:

Aquí Insertar imagen Descripción

3. El programa no va a terminar, con la velocidad del ordenador visibles se calienta, esta vez sin decir que el ciclo de la muerte, la causa de la muerte del ciclo, JDK7 porque la primera interpolación causada por la expansión de la lista cuando un bucle, jdk8 bajo resuelve este problema , pero aún provocar un bucle infinito, la razón es clara.





Resultados menos datos, la causa del error análisis


           Datos menos razón es muy simple, cuando dos hilos operan en el mismo nodo, antes de un hilo después de las operaciones de rosca se sobrescriben. Por ejemplo: Después de hilo 1 tiene un nodo A para ser insertado en la matriz de hash detrás No. 4, después de que el hilo 2 hay dos de hash Nodo B también inserta detrás de la matriz de 4 bits, el resultado debe ser la correcta 4-> A-> B, o 4-> B-> a, No. 4, pero si el acceso nodos 1 y 2 simultáneamente, es decir, el caso Nº 4 no vino al nodo y añadir a, añadir B no tenía tiempo, de modo que 1 y 2 se ven cuatro vacía comienzan volver a agregar 4, el hilo 1 Sume los chips rápidos, rosca a la lenta 2, el hilo 1 así modificado fue sobrescrito hilo 2, en 4-> B, un hilo modificado en una perdida.



Resultados Análisis causa error bucle infinito


           3, ya que los resultados del programa nunca termina, el ordenador se calientan gradualmente, a fin de comprobar el funcionamiento de la CPU con el comando superior, se puede ver pid1977 ya cpu200% en el periodo previo, como se muestra a continuación:

Aquí Insertar imagen Descripción

A continuación, la información de la pila, que jstack Tirada por debajo de la JDK7:

Aquí Insertar imagen Descripción
Como puede verse en la figura: salir en los dos hilos son HashMap.put, la línea de posicionamiento 494 a la HashMap:

Aquí Insertar imagen Descripción
           Este lugar parece dos hilos dentro de los datos que atraviesan el HashMap, esta vez debido a que la lista tiene que tocar el recorrido se ha convertido en un bucle sin fin.

           Causa JDK7 en un bucle infinito que dos hilos simultáneamente expansión refrito, haciendo que la cadena para formar un anillo.

           Cuando JDK7 repetición usando la lista enlazada se convierte en la orden después de la primera método de interpolación, la migración, es decir, A-> B-> C en una C-> B-> A, este momento, si el hilo 1 y 2 mientras que la expansión, tanto creación de un almacenamiento temporal nodo A-> B, la preparación para esta operación, el hilo 1 sigue funcionando en este momento, un hilo temporal 2, el hilo 1 pasa a la C-> B-> a, el nodo B es cierto en este punto de tiempo a, y después pase 2 continúa, seguir operando bajo nodo temporal A-> B, a continuación, resolver una, ir al nodo de hilo 1 se ha colocado anotó una verdadera buena nodo operación, que es B-> a continúa operando, por lo una colocación bien del punto B original, y luego continuar a ganar un nodo de una continúa operando, dejar que un punto B, haciendo que el punto B, punto B a una lista enlazada circular. (Probablemente introducido aquí, detalles, consultar https://www.jianshu.com/p/1e9cf0ac07f4 )

           jdk8 cabeza ya no está usando el método de interpolación, en lugar de utilizar cola de interpolación, después de la inserción del mismo orden de la lista, evitando de este modo el anillo de la cadena lugar, pero un nuevo ciclo de causas de muerte.



La figura jdk8 ejecuta como sigue:

Aquí Insertar imagen Descripción
El problema también se produce seguimiento muertos jdk8 lado, el posicionamiento de código para la línea 1824: Aquí Insertar imagen Descripción
las razones específicas para identificar aún ah, parece ser un anillo de árbol rojo-negro ...

Liberadas dos artículos originales · ganado elogios 0 · Vistas 31

Supongo que te gusta

Origin blog.csdn.net/qq_35217741/article/details/105324735
Recomendado
Clasificación