所以我尝试使用 LWJGL 创建简单的重力,但应用程序随机崩溃并显示 java.util.ConcurrentModificationException
异常(exception)。奇怪的是,这并不总是同时发生。有时它会立即崩溃,但有时它会正常运行 10 分钟然后崩溃。
主要游戏类:
public static ArrayList<Block> blocks;
public Game() {
blocks = new ArrayList<Block>();
for(int i = 0; i < 40; i++)
blocks.add(new BlockTest(i, 21, new float[] {0.4f, 0.6f, 0.7f}, false, 0));
spawnTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
spawnBlock();
}
}, 1000, 1000);
}
public void update() {
for(Block b : blocks)
b.update();
}
block 类:
/** Update block */
public void update() {
if(hasGravity) {
boolean colliding = false;
for(Block b : Game.blocks)
if(b.getBlockID() == 0) {
if(Util.checkBlockCollision(this, b)) {
colliding = true;
setBlockID(0);
}
}
if(fallDelay.over() && !colliding) {
setBlockYPosWithoutBlockSize(y += 2);
fallDelay.start();
}
}
}
堆栈跟踪如下:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at snakybo.gravitytest.block.Block.update(Block.java:26)
at snakybo.gravitytest.Game.update(Game.java:34)
at Main.gameLoop(Main.java:52)
at Main.main(Main.java:21)
(Game.java:34) 是这一行:
b.update();
并且(Block.java:26)是:
for(Block b : Game.blocks)
如果您需要完整的代码,可以在 Github 上找到。
最佳答案
您正在使用多线程。 TimerTask 在单独的线程上运行。
发生的情况是这样的:在计时器任务线程上调用的spawnBlock方法修改了 block 列表(向列表中添加一个)。 在主线程上,调用 update 方法,其中代码迭代 block 列表。
因为在该迭代期间(在另一个线程上执行spawnblock方法期间),一个 block 被添加到 block 列表中,所以您会得到concurrentModificationException。
用“for(Block b : new ArrayList(blocks))”替换“for(Block b : block)”是一个非常简单但性能不佳的解决方案:因为您总是迭代新副本,所以您可以修改原始列表任意数量。
更好的解决方案可能是开始使您的方法同步或重新考虑您的设计,例如将 block 列表包装在同步包装器中。
关于Java 应用程序随机出现 : java. util.ConcurrentModificationException 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16374170/