ConcurrentModificationException in super.update()

I’m not sure how to fix that.



Full explanation:



I’ve got 3 nifty screens I use.



Main Menu (with buttons to generate stuff, save game, etc)

HUD “menu” displayed while in-game.

Options Screen showing the game settings.



If I rapidly go from one screen to the other, or hit ESC to bring the main menu while in-game then hits the Settings button to bring the settings screen up, then hit the Resume button, I will get, eventually at one point, the error in the title. It doesn’t always happen, but I do know that it’s when I close a nifty screen.



Here’s the output:

[java]

Dec 21, 2010 3:13:58 PM com.jme3.app.Application handleError

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.util.ConcurrentModificationException

at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)

at java.util.AbstractList$Itr.next(AbstractList.java:343)

at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:710)

at com.jme3.renderer.RenderManager.render(RenderManager.java:739)

at com.jme3.app.SimpleApplication.update(SimpleApplication.java:216)

at sc.Game.update(Game.java:236)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:144)

at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:141)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:198)

at java.lang.Thread.run(Thread.java:662)

[/java]



From the trace this happens when RenderManager calls RenderViewPort at this point exactly:

[java]

if (processors != null) {

for (SceneProcessor proc : processors) { // <— Right here.

proc.postQueue(vp.getQueue());

}

}

[/java]



The way I “switch” between screen is in the MenuUpdater thread:



[java]

@Override

public synchronized void run() {

while (running) {

if (command.size()>0) {

switch (command.get(0)) {

case 1: // Hide HUD

hideHUD();

break;

case 2: // print a new hint

newHint();

break;

case 3: // Unused

break;

case 4: // flipping panel w/ star preview

if (selectedStar != null) {

flipStarPanel(true);

} else {

flipStarPanel(false);

}

selectedStar = null;

break;

case 5: // reload screen

// unused for now

break;

case 6: // load the OptionsScreen

niftyExit();

loadOptionScreen();

// populate data in options

break;

case 7: // load HUD screen

niftyExit();

loadHUD();

game.isMenuOpen(false);

break;

case 8: // load Start screen

loadStartMenu();

break;

case 9: // screen closing/exiting

niftyExit();

game.isMenuOpen(false);

break;

case 10: // save game

newHint(“Save game not implemented yet.”);

break;

case 11: // load game

newHint(“Load game not implemented yet.”);

break;

case 12: // save settings

niftyExit();

loadStartMenu();

break;

case 13: // cancel settings panel

niftyExit();

loadStartMenu();

break;

case 14: // Applying settings on file

break;

case 999: // Generate a galaxy

hide(“layer_menu”);

newHint(“Building…”);

show(“galGenLayer”);

game.startBuilding();

break;

case 1000: // hide named element

hide();

break;

case 1001: // show named element

show();

break;

case 1002: // update progress panel

doProgress(progress.get(0));

break;

}

command.remove(0);

}

}

}

[/java]



niftyExit(); is pretty simple:

[java]

public void niftyExit() {

nifty.exit();

}

[/java]



So my question is:



How can I avoid that? Should I use a wait() between exiting the current screen and loading the next? I tried that and didn’t see much of an improvement. Maybe giving a longer wait? But I would prefer not to. Then again, it might be something different…



Ideas?

All modifications to the scene graph, including viewports and processors, must be done in the render thread.

I know, but why does it sometimes work 4-5 times in a row then suddenly it gives me a Concurrency exception?



I’m not modifying anything except using nifty.exit. I don’t get it.

If its not deterministic its a threading problem, you have a racing condition somewhere because you either dont execute all scenegraph calls on the OpenGL thread or you have your own threads not properly synchronized.

I see a lot of dangerous things that you’re doing in that “MenuUpdater” thread

Momoko_Fan said:
I see a lot of dangerous things that you're doing in that "MenuUpdater" thread


Care to enlighten me? I could use the knowledge I'm sure. I'm doing the best I can with what I have. :)

I see you have a lot of calls that do things like show HUD, hide elements, etc. I assume they don’t do any of their modifications in the render thread?

If you mean deferring those calls to super.update() then no, and honestly, and at the risk of sounding like a total newbie, I wouldn’t know how to achieve that.

Okay well I don’t see why you need this “new thread” that you’re making here. Its completely unnecessary if all the stuff you do there has to happen in the render thread, you might as well just read those commands in SimpleApplication.simpleUpdate().

1 Like

The existence of that thread stems from when I tried to have nifty update the screen. At that time I was told the main thread was already busy doing its things, so I had to do those GUI updates from a different thread. That’s where it’s coming from.



I guess you mean by your post above to use that MenuUpdater class (after removing the threading) to store whatever changes have to occur. Of course that implies having a precedence ordering, info gathering so things are done properly…



Coming from a single threaded world (way back then multi-threading was so rare it was an untouched subject), so there are many things I have to learn and digest. :confused:

It seems it did the trick.



I did my best to have it crash and it didn’t, so that’s good.



Thanks. Again. :slight_smile:

I don’t understand but I am glad you have it working now :smiley: