Fallo rápido y a prueba de fallos
Cuando uno o más subprocesos atraviesan una colección y otro subproceso modifica la colección (agrega, elimina o modifica), esto se denomina modificación concurrente.
.
La documentación oficial explica el significado de fail-fast en el contexto de la colección HashMap
Esto significa que después de crear el iterador, la colección se puede cambiar excepto la del iterador. método (eliminar) Cualquier cambio en la estructura de la colección provocará una excepción de modificación simultánea.
En el código fuente anterior, puede ver que el iterador llama al método checkForComodification() cuando ejecuta métodos como next(). Este método verifica si modCount es igual a expectModCount. De lo contrario, lanza ConcurrentModificationException. arrojado.
Cuando se crea el objeto, el valor de la variable esperadoModCount se asigna a un valor fijo de modCount, que permanece sin cambios. Si modCount cambia mientras el iterador atraviesa los elementos, se generará una excepción.
Al observar el código fuente, puedes ver que modCount++ se genera al agregar o eliminar elementos de la colección.
Entonces, cuando cambiamos el número de elementos en la colección (agregar, eliminar), modCount cambiará, pero modificar un elemento no cambiará modCount.
Asegúrese de que al realizar modificaciones simultáneas, se aplique un bloqueo de sincronización a todo lo que afecte los cambios de modCount, o utilice un contenedor de clases sincronizado Collections.synchronizedList.
A prueba de fallos: cualquier modificación en la estructura de la colección se realiza en la colección copiada, por lo que no se generará ConcurrentModificationException.
Dos preguntas:
Como puede ver en el código fuente, se aplica un bloqueo cuando se agregan y eliminan elementos de la colección, y luego se permite que los elementos en el subíndice actual agregar o eliminar y, finalmente, completar la copia apuntando la dirección de la matriz original a la nueva matriz. El mecanismo CopyOnWrite está involucrado aquí.
Esto no es una falla rápida, pero agregar y eliminar operaciones a la colección requiere bloqueo, lo que afecta la eficiencia. Además, aumentar el tamaño del objeto puede provocar OOM.
Durante el proceso de recorrido, los elementos del conjunto no son necesariamente el conjunto final de elementos, por lo que solo se puede garantizar la coherencia final.