Search code examples
javahashmapvaadininfinite-loop

Infinite loop in java.util.HashMap


I have some Vaadin code blocking very often here, and I have no idea what the problem can be:

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)

Can somebody suggest any way to further debug this issue? The problem happens very rarely, and it is quite difficult to reproduce.


Solution

  • Based on where it is in the code, the only explanation I can think of is that there are multiple threads accessing and updating that HashMap without synchronizing properly. This can cause the map's data structures to be corrupted, and could result in an infinite loop.

    I can't think of any other reason why java.util.HashMap.getEntry would block. It doesn't do any synchronization or any I/O.


    Roland Illig comments:

    The line number indeed suggests that the code hangs in one of the e = e.next loops.

    That supports my hypothesis. A particular sequence of operations on the hash table performed by two (or more) threads has resulted in the creation of a loop / cycle in one of the hash chains. This corruption has happened because there was inadequate synchronization between the threads performing the operations. It is the kind of thing that happens very rarely, but once it has happened the corruption won't go away.

    Without looking deeply into the Vaadin source code, I can't tell you exactly whether it is a Vaadin bug, or a bug in the way that you are using Vaadin. Either explanation is plausible.

    UPDATE

    Based on this article (provided in a comment below), I would say that it is most likely a problem in the way that your application is synchronizing (or not).