Hay dos tipos de iteradores en Java: a prueba de fallas y a prueba de fallas.
¿Qué significa esto y cuál es la diferencia entre ellos?
Hay dos tipos de iteradores en Java: a prueba de fallas y a prueba de fallas.
¿Qué significa esto y cuál es la diferencia entre ellos?
Respuestas:
Cuál es la diferencia entre ellos ...
"A prueba de fallas" ( en ingeniería ) significa que algo falla de una manera que no causa daños mínimos o nulos. Estrictamente hablando, no existe en Java un iterador a prueba de fallas. Si un iterador falla (en el sentido normal de "falla"), puede esperar que ocurran daños.
Sospecho que en realidad te refieres a iteradores "débilmente consistentes". El javadoc dice:
"La mayoría de las implementaciones de colecciones simultáneas (incluidas la mayoría de las colas) también se diferencian de las convenciones java.util habituales en que sus iteradores y divisores proporcionan un recorrido débilmente consistente en lugar de un error rápido".
Normalmente, una consistencia débil significa que si una colección se modifica al mismo tiempo que una iteración, las garantías de lo que ve la iteración son más débiles. (Los detalles se especificarán en cada javadocs de clases de colección concurrentes).
"Fail-fast" ( en el diseño de sistemas ) significa que la condición de falla se verifica agresivamente para que la condición de falla se detecte (cuando sea posible 1 ) antes de que se pueda hacer demasiado daño. En Java, un iterador a prueba de fallas falla al lanzar un ConcurrentModificationException
.
La alternativa a "fallar rápido" y "débilmente consistente" es semántica donde la iteración falla de manera impredecible; por ejemplo, a veces dar una respuesta incorrecta o lanzar una excepción inesperada. (Este fue el comportamiento de algunas implementaciones estándar de la Enumeration
API en las primeras versiones de Java).
... y son diferentes del iterador que usamos para la colección.
No. Estas son propiedades de los iteradores implementadas por tipos de colección estándar; es decir, "fallan rápido" o "débilmente consistentes" ... cuando se usan correctamente con respecto a la sincronización y el modelo de memoria Java 1 .
Los iteradores a prueba de fallas se implementan típicamente usando un volatile
contador en el objeto de colección.
Iterator
se crea un, el valor actual del contador se incrusta en el Iterator
objeto.Iterator
se realiza una operación, el método compara los dos valores del contador y arroja un CME si son diferentes.Por el contrario, los iteradores débilmente consistentes suelen ser livianos y aprovechan las propiedades de las estructuras de datos internas de cada colección concurrente. No existe un patrón general. Si está interesado, lea el código fuente de las diferentes clases de colección.
1 - El rider es que el comportamiento a prueba de fallas asume que la aplicación se identifica correctamente con respecto a la sincronización y el modelo de memoria. Eso significa que (por ejemplo) si itera ArrayList
sin una sincronización adecuada, el resultado podría ser un resultado de lista dañado. El mecanismo de "falla rápida" probablemente detectará la modificación concurrente (aunque eso no está garantizado), pero no detectará la corrupción subyacente. Como ejemplo, javadoc for Vector.iterator()
dice esto:
"El comportamiento a prueba de fallas de un iterador no se puede garantizar ya que, en términos generales, es imposible hacer garantías estrictas en presencia de una modificación concurrente no sincronizada. Los iteradores de falla rápida se lanzan
ConcurrentModificationException
sobre la base del mejor esfuerzo. Por lo tanto, sería Es incorrecto escribir un programa que dependía de esta excepción para su corrección: el comportamiento rápido de fallas de los iteradores debe usarse solo para detectar errores ".
setArray
cualquier modificación.
Son tipos bastante rápidos y débilmente consistentes :
Iteradores del java.util
lanzamiento del paquete ConcurrentModificationException
si la colección fue modificada por los métodos de la colección (agregar / quitar) mientras se itera
Los iteradores del java.util.concurrent
paquete generalmente iteran sobre una instantánea y permiten modificaciones simultáneas, pero es posible que no reflejen las actualizaciones de la colección después de que se creó el iterador.
Iterator
o Enumeration
especificar el comportamiento como prueba de rápida o prueba de fallos. Son las implementaciones específicas (es decir, los métodos específicos de colección iterator()
/ elements()
etc. que devuelven estos objetos) las que especifican el comportamiento. 2) Las implementaciones típicas de enumeración no son rápidas ni a prueba de fallas .
La única diferencia es que el iterador a prueba de fallas no arroja ninguna excepción, al contrario que el iterador a prueba de fallas.
Si Collection se modifica estructuralmente mientras un subproceso está iterando sobre él. Esto se debe a que funcionan en el clon de Collection en lugar de en la colección original y por eso se denominan iteradores a prueba de fallos.
El iterador de CopyOnWriteArrayList es un ejemplo de iterador a prueba de fallas, también el iterador escrito por ConcurrentHashMap keySet también es un iterador a prueba de fallas y nunca lanza ConcurrentModificationException en Java.
Este escenario se relaciona con el "procesamiento concurrente", significa que más de un usuario accede al mismo recurso. En tal situación, uno de los usuarios intenta modificar ese recurso que causa la 'ConcurrentProcessingException' porque en ese caso otro usuario obtiene datos incorrectos. Tanto este tipo se relacionan con este tipo de situación.
En términos simples,
Fallar rapido :
A prueba de fallos :