2011-05-19 7 views
7

estoy trabajando en una pieza de código con el iterador y conseguir un ConcurrentModificationException en la línea de una cuando corro el programa de mi IDE en windows--es el sistema ConcurrentModificationException dependiente lanzando

LinkedList ll =new LinkedList(); 
    . . . 
    . . . 
    Iterator iter = ll.iterator(); 
    int i=0; 
    while (iter.hasNext()) { 
     // GrammarSection agrammarSection = (GrammarSection) iter.next(); //a 
     String s1 = (String) iter.next(); 
     ll.remove(i); 
     i++; 
    } 

Se espera porque Im modificando la lista mientras estoy iterando para que el iterador de fail-fast arroje una excepción de modificación concurrente. Sin embargo, cuando ejecuto este código en Unix con el servidor Apache, el siguiente método del iterador no arroja ninguna excepción. Entonces, ¿la excepción de modificación simultánea depende del nivel de SO?

+0

¿Está seguro de que su JDK, código y datos son idénticos en ambos entornos? Lo siento, pero no creo que esto sea posible. Java es multiplataforma. ConcurrentModificationException se lanza desde la colección, es decir, desde JDK escrito en java, por lo que no puede depender de la plataforma. – AlexR

+0

Debe aceptar las respuestas anteriores .. –

Respuesta

3

No, no debería. Debería bloquearse de todos modos.

Supongo que podría ser diferente en una JVM diferente, pero de acuerdo con official spec, los iteradores en la lista vinculada deberían fallar.

El sistema operativo no tiene nada que ver con eso.

1

Descubrí cuál podría ser el problema. Cuando su lista tiene 2 elementos, hasNext() devuelve false y funciona sin excepción. Si la lista tiene 3 o más elementos arroja una excepción en todas partes. Así que asegúrese de que su lista tenga la cantidad correcta de elementos.

En cuanto a la dependencia OS - código Java no depende del sistema operativo

De todos modos - Utilización iter.remove() - le van a quitar el elemento de la lista subyacente sin causar la excepción.

El problema con su enfoque es que está modificando la lista subyacente sin que el iterador sepa nada de esa modificación. Entonces debes llevarlo a cabo a través del iterador.

+1

que es un comentario, no una respuesta ... La pregunta del OP es si el lanzamiento, o no, de un CoMo es específico del sistema operativo. Una pregunta genial para mí :) – SyntaxT3rr0r

+0

sí, tengo un párrafo sobre eso ahora. – Bozho

0

Utilice iter.remove(); no ll.remove (i)

Si utiliza la función de eliminación del iterador, no obtendrá una excepción de modificación concurrente.

Sin embargo, para responder a su pregunta; el CME no debe depender del nivel del sistema operativo. Debe haber algún otro problema con su código sobre por qué no está lanzando CME en Unix.

Por cierto, la especificación de los siguientes comentarios

"Tenga en cuenta que el comportamiento a prueba de ayuno de un repetidor no puede ser garantizada, ya que es, en general, imposible ofrecer ninguna garantía duros en presencia de la modificación concurrente no sincronizado Los iteradores a prueba de errores lanzan ConcurrentModificationException sobre la base del mejor esfuerzo. Por lo tanto, sería incorrecto escribir un programa que dependiera de esta excepción para su corrección: el comportamiento a prueba de fallas de los iteradores debería usarse solo para detectar errores ".

+0

Sé muy bien por qué viene la excepción y cómo se puede eliminar. Mi pregunta es: ¿por qué NO recibo la excepción cuando corro en un entorno Unix? – user496934

+0

Mi pregunta es si la excepción de modificación simultánea depende del nivel del sistema operativo? – user496934

+0

La respuesta es no. Debe haber algún otro factor que cause que un CME no se arroje en unix env. –

0

Entonces, ¿la excepción concurrentmodification depende del nivel del sistema operativo?

Tiene dependencia de JMV, pero no en el código que mostró.

// LinkedLists have a member variable called modCount 
// which is an integer which holds the count of modifications 
// made on the list with methods like list.add() list.remove() etc. 
LinkedList ll =new LinkedList(); 
. . . 
. . . 
// When the iterator is created here, it copies the current modCount 
// of the LinkedList into a member of its own called expectedModCount 
Iterator iter = ll.iterator(); 
int i= 0; 
while (iter.hasNext()) { 
    // iter.next() calls a method called checkForComodification 
    // which throws a ConcurrentModificationException if the 
    // current modCount of the original LinkedList is different 
    // from the expectedModCount on this iterator 
    String s1 = (String) iter.next(); 
    ll.remove(i); 
    i++; 
} 

Cuando se accede a la lista y itera en diferentes hilos sin sincronización correcta, la modificación hecha a LinkedList.modCount (cuando LinkedList.add, LinkedList.remove etc son llamados) podría no ser visible para el hilo haciendo la iteración.Por lo tanto, no se garantiza el lanzamiento de ConcurrentModificationException s en general. Pero en el código de un solo subproceso que mostró, no debería haber problemas de visibilidad y la excepción siempre se debe lanzar si se llama alguna vez ll.remove() con éxito después de ll.iterator().

Cuestiones relacionadas