Serie de simultaneidad de JUC (4): [Preguntas frecuentes de la entrevista] Varios métodos para resolver la no seguridad de subprocesos de ArrayList, explique CopyOnWriteArrayList en detalle (ejemplo de código)

No es difícil ejecutar un programa; ¡lo difícil es qué tan lejos puede ejecutarse el programa! —— una semilla feroz

Inserte la descripción de la imagen aquí
Serie de concurrencia JUC

Serie de concurrencia JUC (1): ¿Qué? Escuché que confunde concurrencia y
serie de concurrencia JUC paralela (2): Explicación detallada de la condición para lograr una notificación precisa para despertar
Serie de concurrencia JUC (3): concurrencia en la entrevista, cuando se le pregunte sobre el bloqueo, quedará atónito. )

Uno, ArrayList no es seguro para subprocesos

En la serie anterior de subprocesos múltiples, se mencionó que ArrayList no es seguro en subprocesos múltiples.

Diez subprocesos múltiples en profundidad: solo a partir de diferentes casos, podemos comprender profundamente la inseguridad del subproceso múltiple, para resolver mejor

No importa si no lo ha visto antes, saquemos el código y lo revisemos.

1.1 Ejemplo de código no seguro para subprocesos de ArrayList

public class Demo {
    
    
    public static void main(String[] args) {
    
    
        ArrayList<String> list = new ArrayList<String>();
        for (int i = 0; i < 10000; i++) {
    
    
            new Thread(() -> {
    
    
                list.add(Thread.currentThread().getName());
            }).start();
        }
        try {
    
    
            Thread.sleep(1000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println(list.size());
    }
}

resultado de la operación

Puede ver que el número de adiciones a la longitud de la colección no es la que esperábamos.

En su lugar, puede producirse una sobrescritura.

No es seguro recopilar ArrayList en varios subprocesos.

Inserte la descripción de la imagen aquí

Dos, Vector resuelve la seguridad sin subprocesos de ArrayList

¿No es curioso, por qué se menciona Vector aquí, no solo porque Vector es seguro para subprocesos, sino también porque ArrayList proviene de la interfaz List, por lo que puede ser el que se encuentra con más frecuencia cuando aprende, o puede ser la solución más común para los problemas de no subprocesos de ArrayList en su desarrollo Por supuesto, también se usarán comúnmente las respuestas de la entrevista que suelte.

Pero pero...

Si solo conoces Vector, no es suficiente. ¿Por qué dices eso? ¡Solo una pequeña pregunta!

¿Crees que ArrayList fue el primero en JDK o Vector ?

Su respuesta debe ser ArrayList primero y luego Vector . Todavía hay una pregunta. Vector no está destinado a resolver el problema de no subprocesamiento de ArrayList.

Pero la respuesta puede ser la opuesta: Vector se agregó en JDK1.0 , mientras que ArrayList se agregó en JDK1.2. Entonces, Vector es viejo y ArrayList es el nuevo (por supuesto, 1.2 no es nuevo).

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

2.1 Vector resuelve el ejemplo de código no subproceso de ArrayList

Vector es muy simple de resolver, simplemente reemplace la palabra clave ArrayList con Vector.

 Vector<String> list = new Vector<String>();

Vector excepto

public class Demo {
    
    
    public static void main(String[] args) {
    
    
        Vector<String> list = new Vector<String>();
        for (int i = 0; i < 10000; i++) {
    
    
            new Thread(() -> {
    
    
                list.add(Thread.currentThread().getName());
            }).start();
        }
        try {
    
    
            Thread.sleep(1000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println(list.size());
    }
}

resultado de la operación
Inserte la descripción de la imagen aquí

2.2 Vector es bueno, pero utilícelo con precaución

Aunque Vector es una lista segura para subprocesos, su implementación segura para subprocesos consiste en agregar la palabra clave sincronizada a todas las operaciones. Este método afecta seriamente la eficiencia. Por lo tanto, no se recomienda Vecto.

Inserte la descripción de la imagen aquí

2.3 La respuesta de la entrevista a Vector no es un elemento adicional, solo una respuesta

Además de usarlo con precaución, cuando se reúna en una entrevista, si solo responde a Vector, en realidad no le dará puntos adicionales, porque Vector es una palabra clave antigua y solo puede considerarse como una respuesta.

Pero si puede responder a Vector y decir las siguientes soluciones, entonces puede reflejar la amplitud de su conocimiento.

Tres, synchronizedList resuelve la seguridad sin subprocesos de ArrayList

SynchronizedList es un método proporcionado por Collections, también es muy simple de resolver.

List<String> list = Collections.synchronizedList(new ArrayList());

3.1 SynchronizedList resuelve el ejemplo de código no subproceso de ArrayList

public class Demo {
    
    
    public static void main(String[] args) {
    
    
        List<String> list = Collections.synchronizedList(new ArrayList());
        for (int i = 0; i < 10000; i++) {
    
    
            new Thread(() -> {
    
    
                list.add(Thread.currentThread().getName());
            }).start();
        }
        try {
    
    
            Thread.sleep(1000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println(list.size());
    }
}

resultado de la operación
Inserte la descripción de la imagen aquí

3.2 Ventajas y desventajas de synchronizedList

El rendimiento de la operación de escritura de synchronizedList es mucho mejor que el de CopyOnWriteArrayList que se describe a continuación en la operación de subprocesos múltiples, pero la operación de lectura usa la palabra clave sincronizada, por lo que es mejor leer que CopyOnWriteArrayList.

Mientras haya un lugar sincronizado, es decir, haya un lugar para bloquear, por supuesto, no hay una buena forma de hacerlo en términos de rendimiento.

Por lo tanto, no existe la mejor manera, solo los escenarios de aplicación más adecuados.

Cuatro, CopyOnWriteArrayList

CopyOnWriteArrayList se encuentra principalmente en CopyOnWrite copy-on-write (COW para abreviar), que es una estrategia de optimización en programación de computadoras.

La idea de copiar en escritura es que cuando varios subprocesos leen el mismo recurso al mismo tiempo, obtendrán conjuntamente el recurso al que apunta el puntero, pero cuando algunos subprocesos operan (modifican) el mismo recurso, en realidad harán una copia, mientras que otros El acceso del subproceso al recurso inicial permanece sin cambios.

Se puede entender simplemente que evitar sobrescribir cuando la escritura de datos causó problemas.

4.1 CopyOnWriteArrayList resuelve el ejemplo de código no subproceso de ArrayList

public class Demo {
    
    
    public static void main(String[] args) {
    
    
        List<String> list = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 10000; i++) {
    
    
            new Thread(() -> {
    
    
                list.add(Thread.currentThread().getName());
            }).start();
        }
        try {
    
    
            Thread.sleep(1000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println(list.size());
    }
}

resultado de la operación
Inserte la descripción de la imagen aquí

4.2 Resumen CopyOnWriteArrayList

En base a lo anterior, creo que puede resumir CopyOnWriteArrayList, CopyOnWriteArrayList es mejor que Vector y synchronizedList en lectura, pero el rendimiento de lectura y escritura no es tan bueno como synchronizedList.

Cinco, finalmente

Al final, para una mejor experiencia de lectura, pongo todo lo que quiero decir a continuación, jeje.

Soy semilla de decisiones basadas en mi voluntad, en serio compartir lo que escribí en el blog ha sido el mismo credo.
Si puedes leer esta entrada del blog, significa que todavía estamos muy destinados; espero que te pueda traer algo de ayuda, la creación no es fácil,
quita el conocimiento de mi artículo, tus tres seguidos dejan, me gusta, comenta, sigue , Es mi mayor motivación.

Supongo que te gusta

Origin blog.csdn.net/A_hxy/article/details/108704234
Recomendado
Clasificación