2012-04-18 20 views
8

tengo algo de código Vaadin bloqueo muy a menudo aquí, y no tengo ni idea de lo que el problema puede ser:bucle infinito en java.util.HashMap

Thread 7892: (state = IN_JAVA) 
- java.util.HashMap.getEntry(java.lang.Object) @bci=61, line=349 (Compiled frame; information may be imprecise) 
- java.util.HashMap.containsKey(java.lang.Object) @bci=2, line=335 (Compiled frame) 
- java.util.HashSet.contains(java.lang.Object) @bci=5, line=184 (Compiled frame) 
- com.vaadin.ui.Table.unregisterPropertiesAndComponents(java.util.HashSet, java.util.HashSet) @bci=85, line=1693 (Compiled frame) 
- com.vaadin.ui.Table.refreshRenderedCells() @bci=992, line=1641 (Compiled frame) 
- com.vaadin.ui.Table.valueChange(com.vaadin.data.Property$ValueChangeEvent) @bci=23, line=2897 (Compiled frame) 
- com.vaadin.data.util.IndexedContainer.firePropertyValueChange(com.vaadin.data.util.IndexedContainer$IndexedContainerProperty) @bci=140, line=553 (Compiled frame) 
- com.vaadin.data.util.IndexedContainer.access$1000(com.vaadin.data.util.IndexedContainer, com.vaadin.data.util.IndexedContainer$IndexedContainerProperty) @bci=2, line=64 (Compiled frame) 
- com.vaadin.data.util.IndexedContainer$IndexedContainerProperty.setValue(java.lang.Object) @bci=202, line=915 (Compiled frame) 
- com.aimprosoft.wavilon.backgroundthreads.ChangeCdrThread.insertNewPersonIntoTable(com.aimprosoft.wavilon.model.Person, com.vaadin.ui.HorizontalLayout, com.aimprosoft.wavilon.ui.menuitems.CallContent, com.vaadin.ui.Table) @bci=924, line=208 (Interpreted frame) 
- com.aimprosoft.wavilon.backgroundthreads.ChangeCdrThread$RepaintTableThread.run() @bci=622, line=446 (Compiled frame) 

Puede alguien sugerir una manera de avanzar en la depuración de este tema? El problema ocurre muy raramente, y es bastante difícil de reproducir.

+0

¿Puedes obtener alguna parte del código fuente? – iMysak

+0

En este caso, no es necesario el código fuente actual. He visto esta pila rastrear con la suficiente frecuencia.:) –

+0

@gonvaled Por favor, eche un vistazo a mi respuesta, explica en detalle por qué ve este comportamiento. –

Respuesta

15

Según dónde está en el código, la única explicación que se me ocurre es que hay varios subprocesos que acceden y actualizan ese HashMap sin sincronizar correctamente. Esto puede ocasionar la corrupción de las estructuras de datos del mapa, lo que podría dar como resultado un ciclo infinito.

No puedo pensar en ninguna otra razón por la que java.util.HashMap.getEntry se bloquee. No realiza ninguna sincronización ni ninguna E/S.


comentarios Roland Illig:

El número de línea de hecho sugiere que el código se cuelga en uno de los bucles e = e.next.

Eso apoya mi hipótesis. Una secuencia particular de operaciones en la tabla hash realizada por dos (o más) hilos ha resultado en la creación de un bucle/ciclo en una de las cadenas hash. Esta corrupción ha sucedido porque no hubo una sincronización adecuada entre los hilos que realizan las operaciones. Es el tipo de cosa que sucede muy raramente, pero una vez que ha sucedido la corrupción no desaparecerá.

Sin mirar profundamente en el código fuente Vaadin, no puedo decir exactamente si se trata de un error Vaadin, o un error en la forma en que usted está usando Vaadin. Cualquiera de las explicaciones es plausible.

ACTUALIZACIÓN

Basado en this article (proporcionado en un comentario más abajo), yo diría que lo más probable es un problema en la forma en que su aplicación se sincroniza (o no).

+1

El número de línea de hecho sugiere que el código se cuelga en uno de los bucles 'e = e.next'. –

+0

Tiene razón en que mi formulación es un poco contradictoria. Lo que quise decir es: es * muy difícil * reproducir (tengo que generar muchos datos para la prueba de estrés, y hacer clic en mi aplicación web aleatoriamente para que esto ocurra), pero cada vez que llega a una situación de error * muy a menudo * está mostrando el rastro de la pila que se muestra. Lo siento por mi descuido, pero ayer después de un largo día de depuración me sentía un poco frustrado. – dangonfast

2

¿Está su hilo de fondo sincronizado en la instancia de la aplicación al modificar el componente? Si no, entonces ese es tu problema.

+0

@gonvaled Como Artur dice que * debe * sincronizar el procesamiento en segundo plano con la instancia de la aplicación Vaadin o se encontrará con problemas como este. Consulte este artículo: http://njbartlett.name/2011/05/25/concurrent-vaadin.html para obtener una solución y un código de ejemplo. – hezamu

7

Así que lo que en realidad se está viendo aquí es un hilo de entrar en un bucle infinito evaluar e = e.next

En esencia

e.next == e

Esto ocurre cuando se está poniendo en un HashMap varios subprocesos durante una reestructuración de la mesa

Tome un vistazo a este enlace para obtener más información

A Beautiful Race Condition

Para resolver este bien utilizar un Collections.synchronizedMap o ConcurrentHashMap. Sugiero lo último.

+0

Lamentablemente no puedo cambiar la implementación de las bibliotecas de vaadin (bueno, supongo que podría, pero eso sería demasiado complicado) – dangonfast

+0

@gonvaled ¿Están en github? Puede abrir una solicitud de extracción, o tal vez hay una versión más reciente con una corrección. –