java.util.HashMap中的无限循环

时间:2012-04-18 23:45:54

标签: java hashmap vaadin infinite-loop

我在这里经常有一些Vaadin代码阻塞,我不知道问题是什么:

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)

有人可以建议任何方法来进一步调试此问题吗?这个问题很少发生,很难再现。

3 个答案:

答案 0 :(得分:17)

根据它在代码中的位置,我能想到的唯一解释是有多个线程在没有正确同步的情况下访问和更新HashMap。这可能导致地图的数据结构被破坏,并可能导致无限循环。

我想不出java.util.HashMap.getEntry阻止的任何其他原因。它不执行任何同步或任何I / O.


Roland Illig评论:

  

行号确实表明代码在其中一个e = e.next循环中挂起。

这支持了我的假设。由两个(或更多)线程执行的对散列表的特定操作序列导致在一个散列链中创建循环/循环。发生此损坏是因为执行操作的线程之间的同步不足。这种情况很少发生,但一旦发生,腐败就不会消失。

如果不深入研究Vaadin源代码,我无法确切地告诉您它是否是Vaadin错误,或者是使用 Vaadin的错误。这两种解释都是合理的。

<强>更新

基于this article(在下面的评论中提供),我会说这很可能是您的应用程序同步(或不同步)的方式的问题。

答案 1 :(得分:9)

所以你在这里看到的是一个进入评估e = e.next

的无限循环的线程

本质上

e.next == e

当您在表重组期间通过多个线程放入HashMap时会发生这种情况。

请查看此链接以获取更多信息

A Beautiful Race Condition

要解决此问题,请使用Collections.synchronizedMapConcurrentHashMap。我建议后者。

答案 2 :(得分:2)

修改组件时,后台线程是否在应用程序实例上同步?如果没有,那就是你的问题。