2011-05-01 27 views
1

JAVA使用ArrayList而沒有ConcurrentModificationException(s)的方法?

我有我的比賽一個ArrayList來存儲所有的粒子游戲中。我有一個訪問ArrayList更新物理的更新方法,我有一個渲染方法訪問ArrayList來渲染屏幕上的粒子,以及一個MouseClick偵聽器,當它檢測到MouseClick時,它會向ArrayList添加一個新的粒子。

我的問題是我不斷收到java.util.ConcurrentModificationException。這是因爲當我在同一時間點擊它呈現並且兩個方法都試圖訪問ArrayList。是否有解決方案來同時訪問ArrayList(不同的數據類型?)。

一些代碼,以幫助OUT-

ArrayList的宣言

ArrayList<Particle> ParticleList = new ArrayList<Particle>(); 

粒子類定義

public class Particle { 

int x; 
int y; 
Color colour; 
int type; 
//0:wall 
public Particle(int x,int y,Color colour,int type) 
{ 
    this.x = x; 
    this.y = y; 
    this.colour = colour; 
    this.type = type; 
}` 

Render方法

for(Particle e : this.ParticleList) 
{ 
g.fillRect(e.x, e.y, 1, 1); 
} 
+0

如果您嘗試在迭代2期間添加/刪除一些東西:使用ListIterator.remove/add,但除了在最後添加/刪除它可能會很慢。最有可能你可能需要重新設計數據結構 – bestsss 2011-05-01 08:07:22

回答

5

更新:看來你是沒有多線程訪問,讓我原來的答覆不成立(我會保持它的完整性的緣故)

ConcurrentModificationException在單個線程只發生,如果你在迭代時添加或從集合中刪除。爲了解決這個問題,創建一個新的集合,它是第一個集合的副本,並添加到它。


如果你寫(點擊)比數量少的方式的讀操作,那麼你可以使用 CopyOnWriteArrayList

否則,你將不得不迭代時同步。或者獲取副本(List copy = new ArrayList(original)

+0

所描述的問題不是多線程處理的結果,CoWArrayList具有O(n * n)即使添加也是如此,粒子看起來很多,而且會非常慢。由於這個問題似乎並不是多線程,所以同步不會成功。 – bestsss 2011-05-01 08:05:14

+0

@bestsss我沒有完全明白所描述的問題,這就是爲什麼我有「如果」和「否則」。加入COWAL確實是最慢的操作,這就是爲什麼只有在有少量添加劑的情況下才能使用。此外,我仍然有一個多線程訪問的印象。它看起來像事件線程和主線程一起擺動。 – Bozho 2011-05-01 08:07:20

+0

實際上只有一個線程在執行多個遊戲循環 – liamzebedee 2011-05-01 08:12:15

2

Swing本身隱含地是單線程的。你的點擊和你的渲染應該在同一個線程上。如果你這樣做,你將不會得到ConcurrentModificationException,因爲你只會渲染或處理點擊。

相關問題