I'm processing a lot of events that come from a TCP socket (sets of ten per second), so I'm using multithreading to process those events.
public class MainActivity extends Activity {
...
// In this Map I store the tab name and the associated TabHost.TabSpec instance
private static Map<String, TabHost.TabSpec> Tabs = Collections.synchronizedMap(new LinkedHashMap<String, TabHost.TabSpec>());
// In this Map I store pairs of tab-names and a HashSet of undelivered messages
// It's a class that extends Map<String, HashSet<String>> with some additional functions that doesn't have anything to do with Tabs.
private static NamesListing Names = Collections.synchronizedMap(new LinkedHashMap<String, HashSet<String>>());
// Yes, I know the names don't follow the Java standards, but I keeped them for mantaining the question coherence. I will change it in my code, though.
synchronized private static void ProcessEvent(final String name, final String message) {
// Low-priority thread
final Thread lowp = new Thread(
new Runnable() {
public void run() {
final Iterator<String> iter = Tabs.keySet().iterator();
while (iter.hasNext()) {
final String tabname = iter.next();
// This just returns an int making some calculations over the tabname
final int Status = Names.getUserStatus(tabname, message);
// Same than getUserStatus
if ((Names.isUserSpecial(Status)) && (name.equals(tabname))) {
// This just removes a line from the HashSet
Names.delLine(tabname, message);
}
}
}
});
lowp.setPriority(3);
lowp.start();
}
...
}
Most of time this works right, but sometimes there are some avalanches of those events, and somethimes I get a ConcurrentModificationException:
12-10 14:08:42.071: E/AndroidRuntime(28135): FATAL EXCEPTION: Thread-369 12-10 14:08:42.071: E/AndroidRuntime(28135): java.util.ConcurrentModificationException 12-10 14:08:42.071: E/AndroidRuntime(28135): at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:347) 12-10 14:08:42.071: E/AndroidRuntime(28135): at java.util.LinkedHashMap$KeyIterator.next(LinkedHashMap.java:367) 12-10 14:08:42.071: E/AndroidRuntime(28135): at es.irchispano.chat.MainActivity$6.run(MainActivity.java:244) 12-10 14:08:42.071: E/AndroidRuntime(28135): at java.lang.Thread.run(Thread.java:841)
Note: The 244 line corresponds to the
final String tabname = iter.next();
statement.
It seems weird to me as I'm using a Collections.synchronizedMap and the method that processes those lines is synchronized, so why is it still happening?
Thanks!
---------- Edited ----------
Sorry for the concise initial code; I've tried to simplify as much as possible but obviously it was not a good idea. I'm pasting the actual code. Of course each of those structures are initialized (otherwise I wouldn't have a problem :-)), now I'm going to read all your comments with conscience and I'll post what I'll find out. Thank you all for the support!