Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ConcurrentModificationException超过列表_Java_Concurrency - Fatal编程技术网

Java ConcurrentModificationException超过列表

Java ConcurrentModificationException超过列表,java,concurrency,Java,Concurrency,我正在尝试迭代对象列表。我得到ConcurrentModificationException错误。但是,我不会更改/删除对象。此外,game.getRooms()方法也是同步的。我做错了什么 Iterator<Room> it = game.getRooms().iterator(); while (it.hasNext()) { Room room = it.next(); synchronized (room) {

我正在尝试迭代对象列表。我得到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());
        }
     }
Iterator it=game.getRooms().Iterator();
while(it.hasNext()){
房间=it.next();
(房间){
图像块;
if(room.getTile()==Tiles.WALL){
瓦片=瓦片。墙;
}else if(room.getTile()==Tiles.EXIT){
tile=TileGraphics.exit;
}否则{
瓷砖=瓷砖地面;
}
tile.setAlpha(room.getLight());
tile.draw(room.getX()*tile.getWidth(),room.getY()*tile.getHeight());
}
}
堆栈跟踪:

java.util.ConcurrentModificationException 位于java.util.AbstractList$Itr.checkForComodification(未知源) 位于java.util.AbstractList$Itr.next(未知源) 在game.screens.GameScreen.render(GameScreen.java:62) 位于org.newdawn.slick.state.StateBasedGame.render(StateBasedGame.java:199) 位于org.newdawn.slick.GameContainer.updateAndender(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) 2011年6月7日星期二22:05:03 EEST错误:Game.render()失败-检查游戏代码。 org.newdawn.slick.SlickException:Game.render()失败-检查游戏代码。 位于org.newdawn.slick.GameContainer.updateAndender(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=it.next()

如果此列表正在多线程应用程序中使用,则任何线程都可以 访问列表并使用迭代器修改/迭代支持列表

您的列表是使用同步包装器创建的吗?(例如Collections.synchronizedList(新的ArrayList())

同步列表的声明是不够的,同步方法调用也是不够的。列表迭代的每个地方都需要一个同步块,与列表同步


阅读)

同步getRooms这一事实根本不会影响代码。它只影响对getRooms()的调用

最好的方法是尝试同步(game){game.getRooms();…iterate}


甚至是同步的(game.getRooms()){…iterate}

在另一个线程中肯定有代码在其他地方修改该列表。因此,一个选项是创建列表的副本并(使用foreach)进行迭代:

List copy=newarraylist(game.getRooms());
(房间:复印件){..}

Slick管理逻辑、渲染等的所有线程,因此可能是Slick中的另一个线程在做这件事-可能是在逻辑线程中的某个地方(即,游戏的“update()方法”中的内容)

如果您没有对上面的代码进行任何修改,为什么要同步?您是否在没有同步的情况下尝试过它,以查看它是否有效


考虑到Slick应该为您处理渲染和逻辑线程/循环,我认为如果您稍微放松一点,让Slick来做这件事,您可能会有更好的运气。可能您根本不需要在这里进行同步。

是否有多个线程正在访问这段代码?异常的stacktrace是什么?如果你在获得迭代器之前在整个迭代开始的“游戏”中同步,是否也会发生异常?CME抛出的是哪一行。stacktrace是什么。当我在游戏中同步它时也会发生。修改或生成房间集合的方法也在游戏中同步了吗?然后在游戏中同步。getRooms()列表由服务器发送到客户端。客户端从不修改它,只是经常重新声明它。列表到底是如何发送给客户端的?客户端是如何接收它的?我尝试同步列表出现在列表本身上的每个方法。它没有帮助。它是使用ObjectOutputStream发送的,使用ObjectInputStream接收的。是使用服务器端的collections.synchronizeList创建的列表吗?我猜不是这样的。这确实起作用了。不过,我将尝试修复它,而不是绕开问题。@Rob Fox-这可能是最好的解决方案,具体取决于进行修改的代码。但是在没有看到它的情况下,我无法推荐一个更好的方法。我使用Collections.synchronizedList(new ArrayList())实现了它。根据场景的不同,这种方法的效率可能会降低。这种方法何时会更有效?
List<Room> copy = new ArrayList<Room>(game.getRooms());
for (Room room : copy) {..}