单线程并发Android

时间:2016-12-28 15:51:53

标签: java android concurrency

我仍然处于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)

2 个答案:

答案 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相关的所有问题。