Directorio de artículos
Colección insegura
En aplicaciones de un solo subproceso, generalmente se adopta new ArrayList()
para especificar una colección de Lista para almacenar datos repetibles.
Pero en el subproceso múltiple, a menudo ocurren problemas inesperados. El código es el siguiente:
import java.util.*;
public class ListTest {
public static void main(String[] args) throws InterruptedException {
// 创建list集合
//List<String> lists = Arrays.asList("1", "2", "3");
// 不安全
List<String> lists = new ArrayList<>();
// 开启十个线程增加数据
for (int i = 1; i <= 40; i++) {
new Thread(()->{
lists.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(Thread.currentThread().getName()+"=="+lists);
},String.valueOf(i)).start();
}
}
}
Los resultados de su operación son los siguientes:
operación multiproceso del mismo conjunto de información de objeto, a menudo aparecerán java.util.ConcurrentModificationException
mensajes de error anormales.
Medidas de seguridad proporcionadas en Java
En el lenguaje Java, se proporcionan una nueva colección y java.util.Vector
clase List . Para obtener más información, consulte el siguiente código:
import java.util.*;
public class ListTest {
public static void main(String[] args) throws InterruptedException {
// 创建list集合
//List<String> lists = Arrays.asList("1", "2", "3");
// 不安全
//List<String> lists = new ArrayList<>();
List<String> lists = new Vector<>();
// 开启十个线程增加数据
for (int i = 1; i <= 40; i++) {
new Thread(()->{
lists.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(Thread.currentThread().getName()+"=="+lists);
},String.valueOf(i)).start();
}
}
}
El registro de ejecución es el siguiente:
no aparecerá ningún java.util.ConcurrentModificationException
mensaje de error.
¿Por qué se puede garantizar el funcionamiento seguro de los datos?
Tomado
synchronized
para la implementación del método de bloqueo de llamadas, multiproceso para garantizar la seguridad de la operación de adición.
Colección de listas seguras bajo JUC
En el paquete JUC, hay varias formas de crear una colección segura.
- 方式 一 : Collections.synchronizedList (new ArrayList <> ());
import java.util.*;
public class ListTest {
public static void main(String[] args) throws InterruptedException {
List<String> lists = Collections.synchronizedList(new ArrayList<>());
// 开启十个线程增加数据
for (int i = 1; i <= 40; i++) {
new Thread(()->{
lists.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(Thread.currentThread().getName()+"=="+lists);
},String.valueOf(i)).start();
}
}
}
Ver la lógica de implementación del código fuente subyacente
Determine el tipo de colección de lista entrante, determine si el tipo es
java.util.RandomAccess
, si lo es, use eljava.util.Collections.SynchronizedRandomAccessList
conjunto de construcción, si no, use eljava.util.Collections.SynchronizedList
conjunto de construcción.
La lógica de operación de adición correspondiente en el código fuente es la siguiente:
¡Tome
synchronized
la forma de sincronizar el bloque de código y realice el bloqueo en la operación de adición de los datos!
- Método 2: nuevo CopyOnWriteArrayList ();
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class ListTest {
public static void main(String[] args) throws InterruptedException {
List<String> lists = new CopyOnWriteArrayList<>();
// 开启十个线程增加数据
for (int i = 1; i <= 40; i++) {
new Thread(()->{
lists.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(Thread.currentThread().getName()+"=="+lists);
},String.valueOf(i)).start();
}
}
}
La introducción en el código fuente es la siguiente:
Obviamente, la lógica es la siguiente:
1. Después de llamar al método add, obtenga la
java.util.concurrent.locks.ReentrantLock
información del objeto.
2, ¡llamalock.lock()
para conseguir un candado!
3. Copie el objeto de matriz original y cree una nueva matriz con el tamaño de la matriz original +1.
4. Coloque los nuevos datos en la nueva matriz.
5. ¡Para cualquier operación finalmente, el bloqueo se libera!
Aspecto de rendimiento
¡La operación de bloqueo en el paquete JUC tiene un mejor rendimiento que la sincronización!