我仍然处于Android(用Java)开发游戏的早期阶段,我遇到了一个并发问题,即在我的游戏循环中添加/删除对象。
应用程序有2个独立的片段,一个是控制器,另一个是显示Game循环的SurfaceView。控制器有按钮,提示创建对象,然后将对象添加到游戏循环中。并发问题似乎是随机出现的,但主要是当从存储它的ArrayList中删除一个Object时,另一个被添加到它中以进行绘制。
在跑步过程中碰撞不会发生均匀或同一点,所以我在这里不知所措。我已经将所有For-each循环切换到ListIterator添加/删除调用,认为它可以避免并发问题,但事实证明它是无效的。
我是否必须使用我的Object添加锁定,直到下一次完成draw()或者还有另一种方式?
提前致谢。
编辑:
// Adds new Objects to ArrayList
ListIterator<Projectile> iterator = curr_player.getProjectiles().listIterator();
iterator.add(new_p);
// Code to remove Object when it goes off View Boundaries
public boolean projectileBoundary()
{
Projectile p;
for (ListIterator<Projectile> iterator = curr_player.getProjectiles().listIterator(); iterator.hasNext();)
{
p = iterator.next();
if (p.getX() > p.getXMax())
{
iterator.remove();
return true;
}
}
return false;
}
// Objects drawn to canvas using this function
public void drawProjectiles()
{
for (Iterator<Projectile> iterator = curr_player.getProjectiles().iterator(); iterator.hasNext();)
{
Projectile p = iterator.next();
drawProjectile(p);
}
}
如前所述,只有在删除之前发生删除时,应用程序才会崩溃。这表示更新正在使用同时添加到其中的新对象绘制的ArrayList时出现问题。
应用程序终止于错误: java.util.ArrayList中的java.util.ConcurrentModificationException $ ArrayListIterator.next(ArrayList.java:573)
答案 0 :(得分:0)
如果是并发问题,那么使用线程安全的数据结构。 使用 CopyOnWriteArrayList 而不是 ArrayList 。 CopyOnWriteArrayList是线程安全的
答案 1 :(得分:0)
我没有实现CopyOnWriteArrayList,我无法证明采用这种性能,我只是实现了一个ArrayList,它可以作为所有对象的缓冲区,只需在下一次迭代时添加。这个想法如下:
// Buffer for adding to Projectiles
ListIterator<Projectile> iterator = temp_buffer.listIterator();
iterator.add(new_p);
然后我使用:
将temp_buffer在下一次update()之前附加到我的画布上// Updating Projectiles on Canvas
public void updateProjectiles()
{
// Add temp_buffer to Projectile List
curr_player.getProjectiles().addAll(temp_buffer);
for (Iterator<Projectile> iterator = curr_player.getProjectiles().iterator(); iterator.hasNext();)
{
Projectile p = iterator.next();
p.update();
}
temp_buffer.removeAll(temp_buffer);
}
这成功地解决了我与java.util.ConcurrentModificationException相关的所有问题。