AppletTalk.com Forum Index AppletTalk.com
Java discussions newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

ConcurrentModificationException iterating

 
Post new topic   Reply to topic    AppletTalk.com Forum Index -> Java Language (German)
View previous topic :: View next topic  
Author Message
Alex Magro
Guest





PostPosted: Fri Jun 10, 2005 3:44 pm    Post subject: ConcurrentModificationException iterating Reply with quote



Hi,

ich bekomme die folgende Fehlermeldung:

java.util.ConcurrentModificationException
at java.util.TreeMap$EntryIterator.nextEntry(Unknown Source)
at java.util.TreeMap$KeyIterator.next(Unknown Source)
at simulator.TimeCounterThread.run(TimeCounterThread.java:51)

Ich weiß prinzipiell auch schon woran die liegt: Ich habe eine Klasse
die als Datenelement folgendes besitzt:
private Map nodeList = Collections.synchronizedMap(new TreeMap());

Nun existieren 2 Threads... der eine Thread fügt ständig neue Elemente
in diese Liste ein, der andere Thread greift alle Skeunde auf die Liste
zu und durchläuft sie... d.h. ich verändere die Liste während ich über
sie iteriere.

Das ist böse... ich weiß Wink. Ich habe nun auch in der API gelesen, dass
sowas nicht geht, wegen fail-fast. Das Problem ist nur, wie kann ich
diesen Fehler beheben... im Prunzip würde es mir ja schon reichen, jede
Sekunde eine Kopie von der TreeMap anzufertigen und über diese dann zu
iterieren... nur dummerweise gibt es kein Clone in Map und mit new
funktioniert es auch nicht, da erhalte ich die gleiche Exeption. Gibt es
für mein Problem irgendeine einfache Lösung?

Grüße,
Alex
Back to top
Marco Lange
Guest





PostPosted: Fri Jun 10, 2005 4:18 pm    Post subject: Re: ConcurrentModificationException iterating Reply with quote



Hallo Alex,

Quote:
java.util.ConcurrentModificationException
at java.util.TreeMap$EntryIterator.nextEntry(Unknown Source)
at java.util.TreeMap$KeyIterator.next(Unknown Source)
at simulator.TimeCounterThread.run(TimeCounterThread.java:51)

Ich weiß prinzipiell auch schon woran die liegt: Ich habe eine Klasse
die als Datenelement folgendes besitzt:
private Map nodeList = Collections.synchronizedMap(new TreeMap());

Nun existieren 2 Threads... der eine Thread fügt ständig neue Elemente
in diese Liste ein, der andere Thread greift alle Skeunde auf die Liste
zu und durchläuft sie... d.h. ich verändere die Liste während ich über
sie iteriere.

Das ist böse... ich weiß Wink. Ich habe nun auch in der API gelesen, dass
sowas nicht geht, wegen fail-fast. Das Problem ist nur, wie kann ich
diesen Fehler beheben... im Prunzip würde es mir ja schon reichen, jede
Sekunde eine Kopie von der TreeMap anzufertigen und über diese dann zu
iterieren... nur dummerweise gibt es kein Clone in Map und mit new
funktioniert es auch nicht, da erhalte ich die gleiche Exeption. Gibt es
für mein Problem irgendeine einfache Lösung?

Dir fehlt die richtige Synchronisation. Zwar verwendest Du schon
Collections.syncronizedMap(...), um Deine Map zu wrappen, jedoch löst Du
damit nicht das Problem der Concurrent Modification, da ja der Iterator
nicht mit den Schreibzugriffen synchronisiert wird.

Daher bräuchtest Du eigentlich eine Synchronisation während der Iterator
läuft, so heißen, etwa folgendes:

Object iteratorLock = new Object();
TreeMap map = new TreeMap();
...

Thread 1:
synchronized (iteratorLock) {
// Elemente hinzufügen
map.put(...,...);
...
}

Thread 2:
synchronized (iteratorLock) {
for (Iterator iterator = map.keySet().iterator;
iterator.hasNext(); ) {
....
}
}

Alternativ kannst Du unter JDK 5.0 auch ein Lock bzw. ReadWriteLock
verwenden.

Je nachdem, wie lange das Hinzufügen oder Iterieren dauert, kann das
natürlich durch die Synchronisation langsamer werden, das musst Du
ausprobieren. Ansonsten ist vielleicht doch kopieren angesagt (welches
aber auch synchronisiert werden sollte). Oder Du musst Dir etwas
aufwändigeres einfallen lassen, etwa ein Zwischenspeicher, wo während
des Iterierens neue Elemente kurz zwischengelagert werden können.

Viele Grüße,
Marco

Back to top
Frank Dreyer
Guest





PostPosted: Fri Jun 10, 2005 4:48 pm    Post subject: Re: ConcurrentModificationException iterating Reply with quote



Alex Magro schrieb:
Quote:
ich bekomme die folgende Fehlermeldung:

java.util.ConcurrentModificationException
at java.util.TreeMap$EntryIterator.nextEntry(Unknown Source)
at java.util.TreeMap$KeyIterator.next(Unknown Source)
at simulator.TimeCounterThread.run(TimeCounterThread.java:51)

Ich weiß prinzipiell auch schon woran die liegt: Ich habe eine Klasse
die als Datenelement folgendes besitzt:
private Map nodeList = Collections.synchronizedMap(new TreeMap());

Nun existieren 2 Threads... der eine Thread fügt ständig neue Elemente
in diese Liste ein, der andere Thread greift alle Skeunde auf die Liste
zu und durchläuft sie... d.h. ich verändere die Liste während ich über
sie iteriere.

Das ist böse... ich weiß Wink. Ich habe nun auch in der API gelesen, dass
sowas nicht geht, wegen fail-fast. Das Problem ist nur, wie kann ich
diesen Fehler beheben...

In der Dokumentation zu Collections.synchronizedFoo steht dazu ein
Code-Beispiel (synchronized-Block um die Iterator-Nutzung legen)

Quote:
im Prunzip würde es mir ja schon reichen, jede
Sekunde eine Kopie von der TreeMap anzufertigen und über diese dann zu
iterieren... nur dummerweise gibt es kein Clone in Map und mit new
funktioniert es auch nicht, da erhalte ich die gleiche Exeption. Gibt es
für mein Problem irgendeine einfache Lösung?

Da die TreeMap(Map) und TreeMap(SortedMap) Konstruktoren intern einen
Iterator verwenden, musst du den Konstruktor-Aufruf ebenfalls in einen
synchronized-Block legen.

Back to top
Alex Magro
Guest





PostPosted: Fri Jun 10, 2005 8:50 pm    Post subject: Re: ConcurrentModificationException iterating Reply with quote

Hi,

Quote:
Dir fehlt die richtige Synchronisation. Zwar verwendest Du schon
Collections.syncronizedMap(...), um Deine Map zu wrappen, jedoch löst Du
damit nicht das Problem der Concurrent Modification, da ja der Iterator
nicht mit den Schreibzugriffen synchronisiert wird.

Daher bräuchtest Du eigentlich eine Synchronisation während der Iterator
läuft, so heißen, etwa folgendes:

Object iteratorLock = new Object();
TreeMap map = new TreeMap();
...

Thread 1:
synchronized (iteratorLock) {
// Elemente hinzufügen
map.put(...,...);
...
}

Thread 2:
synchronized (iteratorLock) {
for (Iterator iterator = map.keySet().iterator;
iterator.hasNext(); ) {
....
}
}

Alternativ kannst Du unter JDK 5.0 auch ein Lock bzw. ReadWriteLock
verwenden.

Je nachdem, wie lange das Hinzufügen oder Iterieren dauert, kann das
natürlich durch die Synchronisation langsamer werden, das musst Du
ausprobieren. Ansonsten ist vielleicht doch kopieren angesagt (welches
aber auch synchronisiert werden sollte). Oder Du musst Dir etwas
aufwändigeres einfallen lassen, etwa ein Zwischenspeicher, wo während
des Iterierens neue Elemente kurz zwischengelagert werden können.
Da der Iterations Thread die ganze Zeit läuft, d.h. es wird ständig

durch die Liste iteriert, wird wohl das kopieren das beste sein, denke
ich, oder?

Back to top
Frank Fiedler
Guest





PostPosted: Fri Jun 10, 2005 9:15 pm    Post subject: Re: ConcurrentModificationException iterating Reply with quote

Alex Magro wrote:

Quote:
Nun existieren 2 Threads... der eine Thread fügt ständig neue Elemente
in diese Liste ein, der andere Thread greift alle Skeunde auf die Liste
zu und durchläuft sie... d.h. ich verändere die Liste während ich über
sie iteriere.

Ich habe das mal so gelöst, dass ich das Hinzufügen nicht direkt mache,
sondern die hinzuzufügenden Objekte in eine Queue packe. Diese wird dann
von dem Thread der durchiteriert abgearbeitet, wenn er mit iterieren
fertig ist. Geht nicht in jeder Situation,ist aber auf jeden Fall
einfach. :-)

gruss
Frank

--
e-mail : fiedler.bass<at>web.de

Back to top
Alex Magro
Guest





PostPosted: Sat Jun 11, 2005 10:33 am    Post subject: Re: ConcurrentModificationException iterating Reply with quote

Hi,

Quote:
Ich habe das mal so gelöst, dass ich das Hinzufügen nicht direkt mache,
sondern die hinzuzufügenden Objekte in eine Queue packe. Diese wird dann
von dem Thread der durchiteriert abgearbeitet, wenn er mit iterieren
fertig ist. Geht nicht in jeder Situation,ist aber auf jeden Fall
einfach. Smile
Das geht in meinem Fall, glaube ich zumindest, nicht, da es sich um ein

ständiges iterieren handelt.

Im Prinzip entwickele ich einen Simulator, der u.a. eine Zeitkomponente
und Zufallskomponente besitzt. Da ich nicht so gerne mit realen Sekunden
arbeiten möchte, habe ich einen Thread, der diese "Sekunden" sehr
schnell simuliert.

Da in meiner Simulation die Zeit sich ständig verringert (auch wenn es
eine Sekunge am Anfang ungleich einer Sekunde nach 2 Stunden ist), kann
ich sowas wie von Dir oben beschrieben nicht benutzen, oder?

Grüße,
Alex

Back to top
Paul Ebermann
Guest





PostPosted: Sat Jun 11, 2005 12:52 pm    Post subject: Re: ConcurrentModificationException iterating Reply with quote

"Alex Magro" skribis:

Quote:
Ich habe das mal so gelöst, dass ich das Hinzufügen nicht direkt mache,
sondern die hinzuzufügenden Objekte in eine Queue packe. Diese wird dann
von dem Thread der durchiteriert abgearbeitet, wenn er mit iterieren
fertig ist. Geht nicht in jeder Situation,ist aber auf jeden Fall
einfach. :-)

Das geht in meinem Fall, glaube ich zumindest, nicht, da es sich um ein
ständiges iterieren handelt.

Das Iterieren fängt doch irgendwann an, und hört
irgendwann auf (und geht dann neu los), oder?

Quote:
Im Prinzip entwickele ich einen Simulator, der u.a. eine Zeitkomponente
und Zufallskomponente besitzt. Da ich nicht so gerne mit realen Sekunden
arbeiten möchte, habe ich einen Thread, der diese "Sekunden" sehr
schnell simuliert.

Da in meiner Simulation die Zeit sich ständig verringert (auch wenn es
eine Sekunge am Anfang ungleich einer Sekunde nach 2 Stunden ist), kann
ich sowas wie von Dir oben beschrieben nicht benutzen, oder?

Mir ist nicht ganz klar, was die Zeit mit der
Iteration zu tun hat.

Ich würde sagen, für deinen Zweck ist die TreeMap nicht
gemacht - aber wenn du etwas genauer beschreibst, was du
eigentlich machen willst, können wir dir bestimmt besser
helfen.


Paul
--
Zitieren im Usenet: http://einklich.net/usenet/zitier.htm
Warum Realnamen: http://www.wschmidhuber.de/realname/

Back to top
Frank Fiedler
Guest





PostPosted: Sat Jun 11, 2005 2:41 pm    Post subject: Re: ConcurrentModificationException iterating Reply with quote

Alex Magro wrote:

Quote:
Das geht in meinem Fall, glaube ich zumindest, nicht, da es sich um ein
ständiges iterieren handelt.

Aber irgendwann hast du doch durchiteriert und setzt neu an,oder? Da
müsste dann das einfügen stattfinden, so hatte ich das gemeint.

Quote:
Im Prinzip entwickele ich einen Simulator, der u.a. eine Zeitkomponente
und Zufallskomponente besitzt. Da ich nicht so gerne mit realen Sekunden
arbeiten möchte, habe ich einen Thread, der diese "Sekunden" sehr
schnell simuliert.

Da in meiner Simulation die Zeit sich ständig verringert (auch wenn es
eine Sekunge am Anfang ungleich einer Sekunde nach 2 Stunden ist), kann
ich sowas wie von Dir oben beschrieben nicht benutzen, oder?

Ich bin nicht sicher,ob ich verstanden habe, was du machst, aber als
weitere Idee hätte ich dazu höchstens noch, die Datenstruktur die du
brauchst,selber zu bauen,und dann ist dein Iterator eben fail-never;-)
Habe aber keine Vorstellung, welche Probleme sich daraus möglicherweise
ergeben, da kommt es dann sicher ganz genau drauf an, wofürdu es nimmst.

gruss
ff


--
e-mail : fiedler.bass<at>web.de

Back to top
Marco Lange
Guest





PostPosted: Sat Jun 11, 2005 6:18 pm    Post subject: Re: ConcurrentModificationException iterating Reply with quote

Hi,

Quote:
Da der Iterations Thread die ganze Zeit läuft, d.h. es wird ständig
durch die Liste iteriert, wird wohl das kopieren das beste sein, denke
ich, oder?

Hmmm, in Deinem Originalposting schriebst Du, dass der Thread jede
Sekunde durch die Map (wieso plötzlich Liste?) iteriert. Wenn die Liste
und die darauf basierenden Berechnungen nicht gerade sehr aufwändig
sind, sollte das Iterieren ja nicht so lange dauern.

Wieviele Elemente sind so im Schnitt in der Map?

Viele Grüße,
Marco

Back to top
Alex Magro
Guest





PostPosted: Sun Jun 12, 2005 11:48 am    Post subject: Re: ConcurrentModificationException iterating Reply with quote

Hi,

Marco Lange wrote:
Quote:
Hmmm, in Deinem Originalposting schriebst Du, dass der Thread jede
Sekunde durch die Map (wieso plötzlich Liste?) iteriert. Wenn die Liste
und die darauf basierenden Berechnungen nicht gerade sehr aufwändig
sind, sollte das Iterieren ja nicht so lange dauern.

Wieviele Elemente sind so im Schnitt in der Map?
Man kann nicht so genau sagen, wieviele Elemente "im Schnitt" in der Map

sind. Anfänglich sind viellleicht nur 10.000 Elemente drin,
letztendliches Ziel (so vielleicht nach 24h Laufzeit) sind ca. 3-5 Mio.

Viele Grüße,
Alex

Back to top
Alex Magro
Guest





PostPosted: Sun Jun 12, 2005 12:00 pm    Post subject: Re: ConcurrentModificationException iterating Reply with quote

Hi,

Quote:
Das Iterieren fängt doch irgendwann an, und hört
irgendwann auf (und geht dann neu los), oder?
Das stimmt.


Quote:
Mir ist nicht ganz klar, was die Zeit mit der
Iteration zu tun hat.
Die Iteration läuft fertig, dann wird eine Sekunde gewartet und dann

wird die nächste Iteration gestartet.

Quote:
Ich würde sagen, für deinen Zweck ist die TreeMap nicht
gemacht - aber wenn du etwas genauer beschreibst, was du
eigentlich machen willst, können wir dir bestimmt besser
helfen.
Wieso ist eine TreeMap nicht geeignet für sowas?


Ich habe einen 3 verschiedene Threads:
1.) Erzeugt neue Elemente und fügt sie in die Map ein (zusätzlich werden
noch zahlreiche andere komplizierte Strukturen aufgebaut, für die ich
u.a. einen schnellen Zugriff über eine ID auf die Elemente der Map
benötige). Dieser Thread ist der eigentlich zeitintensive Teil.
2.) Iteriert durch alle Elemente der Map und löscht in Abhängigkeit von
bestimmten Bedingungen Elemente aus der Liste. Generell ist dieser
Prozess nicht so aufwendig wie der 1.), kann jedoch trotzdem manchmal
weitreichende Umstrukturierungen und Prozesse nach sich ziehen (jedoch
nur selten).
3.) Ein letzter Thread, der alle 30 Sekunden eine Ausgabe über die
aktuellen Ergebnisse der Simulation ausgibt.

Damit die Simulation einigermaßen realistisch arbeitet, sollten 1 und 2
unabhängig voneinander laufen. Damit es wirklich realistisch ist, müsste
eigentliche jedes Element der Map einen eigenen Thread besitzen, bei bis
zu 5 Mio Elementen in der Map ist dies wohl mit meinen Ressourcen nicht
mehr durchführbar.

Viele Grüße,
Alex

Back to top
Alex Magro
Guest





PostPosted: Sun Jun 12, 2005 12:42 pm    Post subject: Re: ConcurrentModificationException iterating Reply with quote

Hi,

ich hätte noch eine Frage zu den synchronized-Blöcken. Gibt es
eigentlich irgendeine einfache Regel, um welche Teile ein
synchronized-Block gehört? Muss um das durchiterieren genauso ein
synchronized-Block, wie um das Einfügen und Löschen von Elementen aus
einer Map?

Sollte man sicherheitshalber alle Stellen, die auf die Map zugreifen mit
einem synchronized-Block umrunden?

Viele Grüße und danke,
Alex
Back to top
Paul Ebermann
Guest





PostPosted: Sun Jun 12, 2005 4:12 pm    Post subject: Re: ConcurrentModificationException iterating Reply with quote

"Alex Magro" skribis:

Quote:
Das Iterieren fängt doch irgendwann an, und hört
irgendwann auf (und geht dann neu los), oder?

Das stimmt.

Mir ist nicht ganz klar, was die Zeit mit der
Iteration zu tun hat.

Die Iteration läuft fertig, dann wird eine Sekunde gewartet und dann
wird die nächste Iteration gestartet.

Wenn da mehrere Millionen Elemente in der Map sind,
dauert eine Iteration eine ganze Weile.

Währenddessen kann die TreeMap nicht geändert werden
(dafür ist sie nicht gemacht).

Die Strategie "ich setze alle zwischendurch erstellten
Objekte in eine Warteschlange und füge sie dann auf
einmal ein" passt hier wohl nicht.

Quote:
Ich würde sagen, für deinen Zweck ist die TreeMap nicht
gemacht - aber wenn du etwas genauer beschreibst, was du
eigentlich machen willst, können wir dir bestimmt besser
helfen.

Wieso ist eine TreeMap nicht geeignet für sowas?

Siehe oben - du kannst nur abwechselnd ändern (außer
im Iterator) oder durchgehen, nicht beides gleichzeitig.

Quote:
Ich habe einen 3 verschiedene Threads:
1.) Erzeugt neue Elemente und fügt sie in die Map ein (zusätzlich werden
noch zahlreiche andere komplizierte Strukturen aufgebaut, für die ich
u.a. einen schnellen Zugriff über eine ID auf die Elemente der Map
benötige). Dieser Thread ist der eigentlich zeitintensive Teil.

2.) Iteriert durch alle Elemente der Map und löscht in Abhängigkeit von
bestimmten Bedingungen Elemente aus der Liste. Generell ist dieser
Prozess nicht so aufwendig wie der 1.), kann jedoch trotzdem manchmal
weitreichende Umstrukturierungen und Prozesse nach sich ziehen (jedoch
nur selten).

Muss dieses Iterieren in einer bestimmten Reihenfolge geschehen?
Ist es wesentlich, ob die zwischendurch eingefügten Objekte schon
dabei sind?

Quote:
3.) Ein letzter Thread, der alle 30 Sekunden eine Ausgabe über die
aktuellen Ergebnisse der Simulation ausgibt.

Greift der auf die Map zu?

Quote:
Damit die Simulation einigermaßen realistisch arbeitet, sollten 1 und 2
unabhängig voneinander laufen. Damit es wirklich realistisch ist, müsste
eigentliche jedes Element der Map einen eigenen Thread besitzen, bei bis
zu 5 Mio Elementen in der Map ist dies wohl mit meinen Ressourcen nicht
mehr durchführbar.

Ja.

So wie ich das sehe, brauchst du eine Datenstruktur, in der
das durchgehen/löschen parallel zum Einfügen passieren kann
(und trotzdem nichts schief geht).

Ich würde da (wenn die Iterations-Reihenfolge nicht
zwingend etwas mit der Map-Zuordnung zu tun haben muss)
eine eigene Hash-basierte struktur basteln (vorher in
der richtigen Größe angelegt, Synchronisation nur lokal
pro bucket). Oder eine eigene Baum-basierte Struktur,
die nur lokal synchronisiert.


Paul
--
Alle meine Antworten, Feststellungen, Behauptungen
sind mit AFAIK und IMHO zu lesen und nicht in der
Luft- und Raumfahrt oder Atomindustrie zu verwenden.

Back to top
Display posts from previous:   
Post new topic   Reply to topic    AppletTalk.com Forum Index -> Java Language (German) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.