2012-08-26 43 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'真的是一個阻力,當你考慮它必須做什麼的時候。 –