我正在尝试迭代一个对象列表。我收到ConcurrentModificationException错误。但是我没有更改/删除对象。 game.getRooms()方法也是同步的。我做错了什么?
Iterator<Room> it = game.getRooms().iterator();
while (it.hasNext()) {
Room room = it.next();
synchronized (room) {
Image tile;
if (room.getTile() == Tiles.WALL) {
tile = TileGraphics.wall;
} else if (room.getTile() == Tiles.EXIT) {
tile = TileGraphics.exit;
} else {
tile = TileGraphics.floor;
}
tile.setAlpha(room.getLight());
tile.draw(room.getX() * tile.getWidth(), room.getY() * tile.getHeight());
}
}
堆栈跟踪:
java.util.ConcurrentModificationException at java.util.AbstractList $ Itr.checkForComodification(Unknown Source) at java.util.AbstractList $ Itr.next(Unknown Source) at game.screens.GameScreen.render(GameScreen.java:62) at org.newdawn.slick.state.StateBasedGame.render(StateBasedGame.java:199) 在org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:681) 在org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:408) 在org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:318) 在game.Main.main(Main.java:23) Tue Jun 07 22:05:03 EEST 2011 ERROR:Game.render()失败 - 检查游戏代码。 org.newdawn.slick.SlickException:Game.render()失败 - 检查游戏代码。 在org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:684) 在org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:408) 在org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:318) 在game.Main.main(Main.java:23)
第62行是Room room = it.next();
答案 0 :(得分:4)
当然,代码会在另一个线程中的其他位置修改该列表。因此,一个选项是创建列表的副本并迭代它(使用foreach):
List<Room> copy = new ArrayList<Room>(game.getRooms());
for (Room room : copy) {..}
答案 1 :(得分:3)
如果在多线程应用程序中使用此列表,则任何线程都可以 访问列表并使用迭代器修改/迭代支持列表。
您的列表是否使用同步包装器创建? (例如,Collections.synchronizedList(new ArrayList())。
同步列表的声明是不够的,也不仅仅是同步方法调用。迭代列表的每个位置都需要一个同步块,与列表同步。
答案 2 :(得分:0)
getRooms同步这一事实根本不会影响代码。它只会影响对getRooms()的调用。
最好的方法是尝试同步(游戏){game.getRooms(); .. iterate}
甚至同步(game.getRooms()){... iterate}
答案 3 :(得分:0)
Slick管理逻辑,渲染等所有线程,所以它可能是Slick中的另一个线程正在做 - 可能在逻辑线程中的某个地方(即游戏的'update()方法中的东西)。 / p>
如果您未对上述代码进行任何修改,为什么要同步?您是否在没有同步的情况下尝试过它以确定它是否有效?
鉴于Slick应该为你处理渲染和逻辑线程/循环,我认为你可能会有更好的运气,如果你放松了一点,让Slick做的事情。可能是你根本不需要在这里进行同步。