logo

ConcurrentModificationException in Java

La excepción ConcurrentModificationException ocurre cuando se intenta modificar un objeto simultáneamente cuando no está permitido. Esta excepción suele producirse cuando se trabaja con Clases de colección Java .

Por ejemplo - No está permitido que un hilo modifique una Colección cuando otro hilo está iterando sobre ella. Esto se debe a que el resultado de la iteración queda indefinido con ella. Alguna implementación de la clase Iterator genera esta excepción, incluidas todas aquellas implementaciones de propósito general de Iterator proporcionadas por JRE. Los iteradores que hacen esto se llaman Fallar rapido ya que lanzan la excepción rápidamente tan pronto como se encuentran con dicha situación en lugar de enfrentar un comportamiento indeterminado de la colección en cualquier momento en el futuro.

factorial en c

Nota:No es obligatorio que esta excepción se lance solo cuando algún otro hilo intente modificar un objeto de Colección. También puede suceder si un solo hilo tiene algunos métodos llamados que intentan violar el contrato del objeto. Esto puede suceder cuando un hilo intenta modificar el objeto Colección mientras está siendo iterado por algúniterador rápido, el iterador arrojará la excepción.

Ejemplo

 import java.awt.List; import java.util.*; public class Concurrentmodificationexception { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); Iterator it = list.iterator(); while (it.hasNext()) { Integer value = it.next(); System.out.println('List Value:' + value); if (value.equals(3)) list.remove(value); } } } 

Producción:

ConcurrentModificationException in Java

Este mensaje dice que la excepción se produce cuando se llama al siguiente método ya que el iterador está iterando la lista y estamos haciendo modificaciones en ella simultáneamente. Pero si realizamos modificaciones en el mapa hash como se indica a continuación, no se generará ninguna excepción ya que el tamaño del mapa hash no cambiará.

Por ejemplo-

 import java.awt.List; import java.util.*; public class concurrentmodificationexception { public static void main(String[] args) { HashMap map = new HashMap(); map.put(1, 1); map.put(2, 2); map.put(3,3); Iterator it = map.keySet().iterator(); while(it.hasNext()) { Integer key = it.next(); System.out.println('Map Value:' + map.get(key)); if (key.equals(2)) { map.put(1, 4); } } } } 

Producción:

cartero
 Map Value:1 Map Value:2 Map Value:3 

Este ejemplo funciona completamente bien ya que mientras el iterador recorre el mapa, el tamaño del mapa no cambia. Sólo el mapa se actualiza en el si declaración .

Constructores de ConcurrentModificationException

Hay 4 tipos de constructores de ConcurrentModificationException:

  1. public ConcurrentModificationException()-
    Esto crea una excepción ConcurrentModificationException sin parámetros.
  2. excepción de modificación concurrente pública (mensaje de cadena)
    Esto crea una excepción ConcurrentModificationException con un mensaje detallado que especifica la excepción.
  3. excepción de modificación concurrente pública (causa arrojable)
    Esto crea una ConcurrentModificationException con una causa y un mensaje que es (cause==null?null:cause.toString()). La causa se recupera posteriormente mediante Throwable.getCause().
  4. public ConcurrentModificationException (mensaje de cadena, causa arrojable)
    Esto crea una excepción ConcurrentModificationException con un mensaje detallado y una causa. (causa==nulo?null:causa.toString()). Posteriormente, Throwable.getMessage() recupera el mensaje y Throwable.getCause() recupera la causa.

¿Cómo evitar ConcurrentModificationException en un entorno multiproceso?

Para evitar ConcurrentModificationException en un entorno de subprocesos múltiples, podemos seguir las siguientes formas:

convertir cadena a entero
  1. En lugar de iterar sobre la clase de colección, podemos iterar sobre la matriz. De esta forma podemos trabajar muy bien con listas de tamaño pequeño, pero esto mermará el rendimiento si el tamaño del array es muy grande.
  2. Otra forma puede ser bloquear la lista colocándola en el bloque sincronizado. Este no es un enfoque eficaz, ya que se renuncia al único propósito de utilizar subprocesos múltiples.
  3. JDK 1.5 o superior proporciona las clases ConcurrentHashMap y CopyOnWriteArrayList. Estas clases nos ayudan a evitar excepciones de modificación concurrente.

¿Cómo evitar ConcurrentModificationException en un entorno de un solo subproceso?

Al utilizar la función remove() del iterador, puede eliminar un objeto de un objeto de colección subyacente.