Java 单线程并发Android

Java 单线程并发Android,java,android,concurrency,Java,Android,Concurrency,我还在用Android(Java)开发游戏的早期阶段,在游戏循环中添加/删除对象时遇到了并发问题 该应用程序有两个独立的片段,一个是控制器,另一个是显示游戏循环的SurfaceView。控制器有按钮,提示创建对象,然后将对象添加到游戏循环中。并发性问题似乎是随机出现的,但主要是当一个对象从存储它的ArrayList中删除,另一个对象被添加到要绘制的ArrayList中时 在跑步过程中,碰撞并不是均匀发生的,也不是在同一点发生的,所以我在这里不知所措。我已经将所有For-each循环切换到List

我还在用Android(Java)开发游戏的早期阶段,在游戏循环中添加/删除对象时遇到了并发问题

该应用程序有两个独立的片段,一个是控制器,另一个是显示游戏循环的SurfaceView。控制器有按钮,提示创建对象,然后将对象添加到游戏循环中。并发性问题似乎是随机出现的,但主要是当一个对象从存储它的ArrayList中删除,另一个对象被添加到要绘制的ArrayList中时

在跑步过程中,碰撞并不是均匀发生的,也不是在同一点发生的,所以我在这里不知所措。我已经将所有For-each循环切换到ListIterator的add/remove调用,认为这可以避免并发问题,但事实证明它是无效的

在下一次完成draw()之前,我是否必须对对象添加使用锁定,还是有其他方法

提前谢谢

编辑:

//将新对象添加到ArrayList
ListIterator迭代器=curr_player.getProjectles().ListIterator();
迭代器.add(new_p);
//用于在对象脱离视图边界时删除该对象的代码
公共布尔投影边界()
{
射弹p;
for(ListIterator iterator=curr_player.GetProjectles().ListIterator();iterator.hasNext();)
{
p=迭代器.next();
if(p.getX()>p.getXMax())
{
iterator.remove();
返回true;
}
}
返回false;
}
//使用此函数绘制到画布的对象
公共射弹()
{
for(Iterator Iterator=curr_player.getprojectles().Iterator();Iterator.hasNext();)
{
p=iterator.next();
牵引弹(p);
}
}
如前所述,只有在删除之前删除应用程序时,应用程序才会崩溃。这表示在同时向其添加新对象的情况下更新正在绘制的ArrayList时出现问题

应用程序在以下错误中终止:
java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)处的java.util.ConcurrentModificationException如果是并发问题,则使用线程安全数据结构。
使用CopyOnWriteArrayList代替ArrayList。CopyOnWriteArrayList是线程安全的

如果是并发问题,则使用线程安全的数据结构。
使用CopyOnWriteArrayList代替ArrayList。CopyOnWriteArrayList是线程安全的

而不是实现CopyOnWriteArrayList,我无法证明采取这种性能打击是合理的,我只是实现了一个ArrayList,作为所有对象的缓冲区,这些对象将在下一次迭代中添加。其思路如下:

// Buffer for adding to Projectiles
ListIterator<Projectile> iterator = temp_buffer.listIterator();
iterator.add(new_p);
//用于添加到投射物的缓冲区
ListIterator迭代器=临时缓冲区。ListIterator();
迭代器.add(new_p);
然后,在下次更新()之前,我使用以下方法将临时缓冲区附加到画布:

// 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);

}
//在画布上更新投射物
public void updateprojectles()
{
//将临时缓冲区添加到投射物列表
curr_player.getprojectles().addAll(临时缓冲区);
for(Iterator Iterator=curr_player.getprojectles().Iterator();Iterator.hasNext();)
{
p=iterator.next();
p、 更新();
}
临时缓冲区。移除所有(临时缓冲区);
}

这成功地解决了我与java.util.ConcurrentModificationException相关的所有问题。

我没有实现CopyOnWriteArrayList,我无法证明接受这种性能影响是合理的,我只是实现了一个ArrayList,作为下一次迭代中添加的所有对象的缓冲区。其思路如下:

// Buffer for adding to Projectiles
ListIterator<Projectile> iterator = temp_buffer.listIterator();
iterator.add(new_p);
//用于添加到投射物的缓冲区
ListIterator迭代器=临时缓冲区。ListIterator();
迭代器.add(new_p);
然后,在下次更新()之前,我使用以下方法将临时缓冲区附加到画布:

// 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);

}
//在画布上更新投射物
public void updateprojectles()
{
//将临时缓冲区添加到投射物列表
curr_player.getprojectles().addAll(临时缓冲区);
for(Iterator Iterator=curr_player.getprojectles().Iterator();Iterator.hasNext();)
{
p=iterator.next();
p、 更新();
}
临时缓冲区。移除所有(临时缓冲区);
}

这成功地解决了我与java.util.ConcurrentModificationException相关的所有问题。

单线程并发?您是否费心阅读我写的内容或只是标题?请发布一些相关代码。此外,如上文所述,如果只有一个线程,那么就不能有并发问题。由于同时发生添加/删除操作,代码抛出错误“java.util.ConcurrentModificationException at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)”。如果这不是并发,也许我遗漏了什么。我将包括一些代码。ConcurrentModificationException不一定是并发问题。这仅仅意味着当迭代器对集合进行迭代时,集合的内容发生了更改。不需要涉及并发。单线程并发?你是否费心阅读我写的内容或只是标题?请发布一些相关代码。此外,如上文所述,如果只有一个线程,那么就不能有并发问题。由于同时发生添加/删除操作,代码抛出错误“java.util.ConcurrentModificationException at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)”。如果这不是并发,也许我遗漏了什么。我将包括一些代码。ConcurrentModificationException不一定是并发问题。这仅仅意味着当迭代器对集合进行迭代时,集合的内容发生了更改。不需要涉及并发性。我唯一关心的是这个列表将在possi中进行大量重构