2012-04-18 5 views
8

Ich habe einige Vaadin Code sehr oft hier blockiert, und ich habe keine Ahnung, was das Problem sein kann:Endlosschleife in 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) 

Kann jemand irgendeine Art und Weise vorschlagen debug dieses Problem zu fördern? Das Problem tritt sehr selten auf und ist ziemlich schwierig zu reproduzieren.

+0

können Sie ein Stück Quellcode bekommen? – iMysak

+0

In diesem Fall ist kein aktueller Quellcode erforderlich. Ich habe diese Stack-Spur oft genug gesehen.:) –

+0

@gonvaled Bitte werfen Sie einen Blick auf meine Antwort, es erklärt im Detail, warum Sie dieses Verhalten sehen. –

Antwort

15

Basierend auf, wo es im Code ist, ist die einzige Erklärung, die ich denken kann, dass es mehrere Threads gibt, die auf HashMap zugreifen und aktualisieren, ohne richtig zu synchronisieren. Dies kann dazu führen, dass die Datenstrukturen der Zuordnung beschädigt werden und zu einer Endlosschleife führen können.

Ich kann mir keinen anderen Grund vorstellen, warum java.util.HashMap.getEntry blockieren würde. Es führt keine Synchronisierung oder keine E/A durch.


Roland Illig Kommentare:

Die Zeilennummer schlägt in der Tat, dass der Code in einer der e = e.next Schlaufen hängt.

Das unterstützt meine Hypothese. Eine bestimmte Sequenz von Operationen in der Hash-Tabelle, die von zwei (oder mehr) Threads ausgeführt wird, hat zur Erzeugung einer Schleife/eines Zyklus in einer der Hash-Ketten geführt. Diese Beschädigung ist aufgetreten, weil zwischen den Threads, die die Operationen ausführen, eine unzureichende Synchronisierung stattgefunden hat. Das passiert sehr selten, aber sobald es passiert ist, wird die Korruption nicht verschwinden.

Ohne tief in den Vaadin-Quellcode zu schauen, kann ich Ihnen nicht genau sagen, ob es ein Vaadin-Bug ist, oder ein Bug in der Art, wie Sie mit Vaadin sind. Jede Erklärung ist plausibel.

UPDATE

Basierend auf this article (in einem Kommentar unten zur Verfügung gestellt), würde ich sagen, dass es höchstwahrscheinlich ein Problem in der Art und Weise ist, die Ihre Anwendung (oder nicht) synchronisiert.

+1

Die Zeilennummer legt nahe, dass der Code in einer der "e = e.next" -Schleifen hängt. –

+0

Sie haben tatsächlich Recht, dass meine Formulierung ein wenig widersprüchlich ist. Was ich meinte ist: es ist * sehr schwierig * zu reproduzieren (ich muss viele Daten für den Stresstest generieren und nach dem Zufallsprinzip auf meine Webanwendung klicken), aber wann immer es eine Fehlersituation erreicht, * sehr oft * Es zeigt die gezeigte Stapelspur. Sorry für meine Schlamperei, aber gestern nach einem langen Debug-Tag fühlte ich mich ein wenig frustriert. – dangonfast

2

Ist Ihr Hintergrund-Thread in der Anwendungsinstanz synchronisiert, wenn Sie die Komponente ändern? Wenn nicht, dann ist das dein Problem.

+0

@gonvaled Wie Artur sagt, * muss * du deine Hintergrundverarbeitung mit der Vaadin-Anwendungsinstanz synchronisieren oder es treten Probleme wie diese auf. Siehe diesen Artikel: http://njbartlett.name/2011/05/25/concurrent-vaadin.html für eine Lösung und Beispielcode. – hezamu

7

Also, was Sie wirklich sehen hier ist ein Thread in einer Endlos-Schleife e = e.next

Im Wesentlichen

e.next == e

Dies geschieht Auswertung gehen, wenn Sie in eine HashMap von mehreren Threads während ein Putting Tabelle umstrukturieren.

Werfen Sie einen Blick auf diesen Link für weitere Informationen

A Beautiful Race Condition

Um dies zu lösen, entweder eine Collections.synchronizedMap oder ConcurrentHashMap zu verwenden. Ich schlage das letztere vor.

+0

Leider kann ich die Implementierung der Vaadin-Bibliotheken nicht ändern (naja, ich könnte es, aber das wäre viel zu kompliziert) – dangonfast

+0

@gonvaled Sind sie auf Github? Sie können eine Pull-Anfrage öffnen, oder vielleicht gibt es eine neuere Version mit einem Fix in. –