2016-11-17 57 views
0

我使用畫布,在屏幕上移動對象時,當一個對象碰到畫布左側(x = 0)時,同一類型的另一個對象被實例化,以及開始在屏幕上移動。Android遊戲循環中的java.util.ConcurrentModificationException

一切工作正常,幾個對象被創建並開始在屏幕上移動。

在某一點上,我收到一個併發修改例外在我的run方法在遊戲循環是,其中gameObjs是一個ArrayList:

@Override 
public void run() { 

    while(isRunning){ 
     if(!myHolder.getSurface().isValid()) 
      continue; 
     Canvas canvas = myHolder.lockCanvas(); 
     canvas.drawRect(0,0,canvas.getWidth(), canvas.getHeight(), pWhite); 


     for(MyGameObject gameObj : gameObjs){ 
      gameObj.move(canvas); 
     } 

     myHolder.unlockCanvasAndPost(canvas); 
    } 

} 

我試圖用一個Iterator,但仍然得到相同的錯誤。

我真的很感謝你的幫助。先謝謝你!如果這樣的事情是發生在你的代碼

+1

什麼類型的對象是'gameObjs'? (即'ArrayList'?)另一個正在運行的線程是添加/刪除此集合中的項目嗎?如果發生這種情況並且允許,可以使用'CopyOnWriteArrayList'或其他允許併發修改的集合... – BretC

+0

對不起,我沒有指定gameObjs是ArrayList – LDG

+0

_「我沒有指定gameObjs是一個ArrayList「_但在問題中您具體說:_」...其中gameObjs是一個ArrayList「_。 –

回答

1

Collections.synchronizedList(...)將無法正常工作。(拋出一個ConcurrentModificationException的...)

public class ConcurrentTest { 

    public static void main(String[] args) { 
     List<String> things = new ArrayList<>(); 

     Runnable modifyThread =() -> { 
      while(true) { 
       for(int k = 0; k < 1000; k++) { 
        things.add(String.valueOf(k)); 
       } 

       while(!things.isEmpty()) { 
        things.remove(0); 
       } 
      } 
     }; 

     Runnable readThread =() -> { 
      while(true) { 
       for(String thing : Collections.synchronizedList(things)) { 
        System.out.println(thing); 
       } 
      } 
     }; 

     new Thread(modifyThread).start(); 
     new Thread(readThread).start(); 
    } 
} 

試圖找到其他地方,這列表正在修改中。當您迭代它時,必須有另一個線程操縱集合。

您可以在迭代之前獲取列表的副本。

例如,在上面的代碼,嘗試...

for(String thing : new ArrayList<>(things)) { 

...而不是...

for(String thing : Collections.synchronizedList(things)) { 

...你將不再得到一個異常(但是這仍然不會是「正確的」,如果你運行它,你會看到被打印出來零點負荷......)

更妙的是,保持讀取環路...

for(String thing : things) { 

...但改變列表類型...

List<String> things = new CopyOnWriteArrayList<>(); 
+0

謝謝@BretC我正在使用相同的循環,我剛剛修改列表** CopyOnWriteArrayList **,完美的作品! – LDG