2012-08-26 39 views
0

我一直在寻找这么难以找到答案,但我不知道我做错了什么。我正在学习如何使用JAVA线程。事情是我正在做一个太空船游戏。我有一个创建敌人的方法(这些敌人被添加到一个ArrayList中,它被绘制为使得运动效果好,这很好)。我有另一种方法,在这个ArrayList中查看那些已经死亡的敌人(死亡是一个布尔值,如果敌人消失或者被杀死的话会变为真),如果它们是(死亡),则从ArrayList中删除那些再画)。我有一个使用createEnemy方法的线程(它工作正常)。现在问题来了,我需要使用这个ereaseEnemy方法,但它给我和并发错误,我已经尝试在两个方法上使用同步,但ereaseEnemy方法从未开始工作。不知道如何解决这个问题。我应该停止第一个线程(创建者)来完成其他工作?我在这里错过了什么?谢谢!去除敌人ArrayList上的Java并发性

for (Enemigo enemigo1 : enemigos) { 
    if (!enemigo1.isEstaVivo()) { enemigos.remove(enemigo1); } 
} 
+4

你可能根本不应该使用多线程。 – SLaks

+1

有关如何从ArrayList中删除条目的示例代码? – kosa

+0

好吧,它会工作,但我不知道它怎么不使用它们。我很确定我必须使用创建者线程,这是我可以继续提供敌人的唯一方法。但是,正如我所说的,不知道我该如何清理那个敌人名单。如果我不这样做,保持增长和增长。有什么建议? – MBRebaque

回答

0

代码你不应该试图把自己的线程同步。让Java通过使用java.util.concurrent类来为您做到这一点。在你的情况下,我会看看ConcurrentLinkedQueueConcurrentMap恒定的访问时间。您可以使用船名作为地图的关键字。

您仍然需要控制对敌人设置dead标志,以便它的访问由多个线程正确处理。数据存储不会为您完成,它只会确保您的所有线程都具有一致的数据存储状态。

http://docs.oracle.com/javase/6/docs/api/index.html?java/util/concurrent/package-summary.html

+0

好吧,我要去看看它。我会回来告诉我是否修正了这个问题。 – MBRebaque

5

你真的应该张贴违规代码,但我可以做一个猜测:你迭代的ArrayList您在调用list.remove(o)内循环。抛出的异常是ConcurrentModificationException。迭代时,您不允许调用List.remove()方法中的任何一种;您必须使用Iterator.remove()。这排除了此用例的增强for循环的用法。在删除之前,你的代码更改为

for (Iterator<Enemigo> iter = enemigos.iterator(); iter.hasNext();) 
    if (!iter.next().isEstaVivo()) iterator.remove(); 
+0

我有点怀疑。我想他是在调用remove(index)。 – kosa

+0

@Nambari他没有使用'remove(index)' – oldrinb

+0

@veer:enemigos.remove(enemigo1);我假设enemigos是列表,他正在调用enemigos.remove(enemigo1);根据索引删除。不是吗? – kosa

0

两个候选条件的解决方案

1)使您的清单复印件(需要注意的性能问题,如果规模过大)

ArrayList<enemigo> enemigosCopy= new ArrayList<enemigo>(); 
enemigosCopy.addAll(enemigos); 
//Do your deleting thing on enemigosCopy 

2)使用迭代器

Iterator i =enemigos.iterator(); 
while (i.hasNext()) { 
    enemigo o = i.next(); 
    if (!enemigo1.isEstaVivo()) {  
    i.remove(o);  
    }    
} 
+0

为什么要删除?他应该通过检查每个元素是否被添加来构建**新列表。 (Enemigo e:enemigos)如果(e.isEstaVivo())enemigosCopy.add(e);' –

+0

好的,但我对此有疑问,我会渲染敌人的形式de copyList,但我仍然有他们所有的原始列表? – MBRebaque

+0

是的,原稿保持不变。请注意,重建方法实际上可能更具性能。 'ArrayList.remove'真的是一个阻力,当你考虑它必须做什么的时候。 –