Excepción de modificación concurrente (ArrayList)
ArrayList no es seguro
la razón:
Debido a que el método de adición no está bloqueado debido a la alta concurrencia , este método no es seguro.
Motivado:
java.util.ConcurrentModificationException
Excepción de modificación concurrente alta
Demostración de código
public class ContainerNotSafeDemo{
public static void main(Stirng[] args){
List<String> list=new ArrayList<>();
for(int i=1;i<30;i++){
new Thread(()->{
list.add(UUID.randomUUID().toString().subString(0,8));
System.out.println(list);
},String.valueOf(i).start());
}
}
}
solución:
1) Use el método Vector para reemplazar el método ArrayList, porque el método add de Vector agrega bloqueo sincronizado
new Vector<>()
2) Utilice las herramientas de Colecciones:
Collections.syncronizedList(new ArrayList<>())
Complemento: Colección representa la interfaz y Colecciones representa la clase de herramienta auxiliar de la interfaz integrada
3) Utilice copia en escritura , es decir, separación de lectura y escritura
CopyOnWriteArrayList
El contenedor CopyOnWrite es el contenedor para copiar en escritura. Cuando agregue elementos a un contenedor, no los agregue directamente al objeto contenedor actual [], sino que primero copie el objeto contenedor actual [], copie un nuevo objeto contenedor [] newElements y luego agréguelo al objeto contenedor [] newElements Elemento, después de agregar el elemento, establezca la referencia del contenedor original al nuevo contenedor setArray (newElements).
La ventaja de hacer esto es que el contenedor CopyOnWrite se puede leer simultáneamente sin bloquear, porque el contenedor actual no agregará ningún elemento. Por lo tanto, el contenedor CopyOnWrite también es una idea de separación entre lectura y escritura. La lectura y la escritura están en contenedores diferentes.
Colocar
ArraySet también es una clase insegura, al igual que ArrayList. También hay tres soluciones, la segunda se usa Collections.syncronizedSet()
y la tercera es el CopyOnwriteArraySet()
método usado para separar la lectura y escritura de Set . Pero CopyOnwriteArraySet()
la implementación subyacente sigue siendoCopyOnwriteArrayList()
Preguntas comunes de la entrevista:
¿Cuál es la capa inferior de HashSet?
La capa inferior de HashSet es HashMap
La razón por la que el método add de Set tiene un solo valor:
El método add call de Set sigue siendo map.put, el valor de add es la clave de put y el valor de put es una constantePresent
Mapa
Lo mismo que los 2 anteriores no son seguros, el nuevo HashMap <> (). put
(Xx, xx) no es seguro
usarCollections.syncronizedMap()
Hay una cierta diferencia que usa el tercer métodonew ConcurrentHashMap<>()