背景
我正在制作一个使用websockets与客户端交互的游戏,而Threads则用于运行主游戏循环(在Game类中)。为了限制Websocket Endpoint发送游戏更新消息的次数(大约60fps),我还在Websocket Endpoint中使用了TimerTask。
问题:
当处理对象之间的碰撞检测时,事情开始出错。将修改后的游戏元素集合转换为JSON(我使用gson
)将其发送到客户端时出现错误(在下面的代码中显示为 things
,它是一个内部有对象的ArrayList
。
错误是java.util.ConcurrentModificationException
。经过一些研究,我发现在删除当前索引上的项目时,您不能使用带for
的简单break
循环。所以我尝试了一些常用的修复方法,并且使用迭代器,我坚持使用最受欢迎的修复程序:
第一个解决方案:
private void collisionDetectionHandler() {
for (Iterator<Thing> iterator = things.iterator(); iterator.hasNext(); ) {
Thing thing = iterator.next();
boolean colliding = collisionDetection(player, things);
if(colliding){
iterator.remove();
}
}
}
然而,这并没有完全解决它。是的,它使它运行得更顺畅,但我偶尔也会得到同样的错误。
我想我已经找到了原因,但我没有一个体面的想法如何解决它:(我认为)有时候这个方法仍然是从列表中删除元素,而同时Websocket正在转换它与JSON相同的列表将其发送到客户端。
我发现了一些弱的解决方法但没有什么好处:
在发送游戏更新之前,将我的Game类中的上述方法设置为public并在Websocket Endpoint内调用它是有效的,但这完全拆分了游戏逻辑,因为所有其他更新都在Game类中的Thread内处理...