2016-08-01 12 views
-2

これはよくある質問ですが、私はコードで解決する方法に固執しています。ArrayListのスローエラー:異なるクラスのコードからの "Concurrent Modification Exception"

グラフィックスウィンドウに余分な "カメ"を追加できるボタンがGUIにあります。これは、ガーレーループ構造からの群れの動作を示すarraylistにカメを追加します。どのように私はそれを作ることができるので、私はこのエラーが表示されない限り、私が望むように多くのカメを追加することができますか?次のように

ゲームループがある:ここ

private void gameLoop() 
    {  
     while(true) //The order in which the turtles move, and when which algorithm is executed 
     { 
      for (int i = 0; i < turtles.size(); i++) //for each turtle, perform the set algorithm 
      { 
       (turtles.get(i)).unDrawTurtle(); 
       (turtles.get(i)).update(1000);    
       hello.setText("X: " + (turtles.get(i)).getPositionX() + " Y: " + (turtles.get(i)).getPositionY());     
      } 

      for (int i = 0; i < turtles.size(); i++) //for each turtle, perform the set algorithm 
      {    
       (turtles.get(i)).cohesian(turtles); //MAKE BOIDS ATTRACT 
      } 

      for (int i = 0; i < turtles.size(); i++) //for each turtle, perform the set algorithm 
      {    
       (turtles.get(i)).drawTurtle(); 
      }       

      for (int i = 0; i < turtles.size(); i++) //for each turtle, perform the set algorithm 
      { 
       (turtles.get(i)).wrapPosition((turtles.get(i)).getPositionX(), (turtles.get(i)).getPositionY()); 
      } 

      //Here we are making sure the turtles are on the screen     

      Utils.pause(deltaTime/2); 
     } 

はArrayListにカメを追加するボタンのコードである:

addTurtleButton.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent event) 
      { 
       turtles.add(new RandomTurtleB(canvas, 400, 300, currentSpeed, 0)); 
      } 
     }); 

     removeTurtleButton.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent event) 
      { 
       turtles.remove(turtles.size() - 1); 
       canvas.removeMostRecentLine(); 
       canvas.removeMostRecentLine(); 
       canvas.removeMostRecentLine(); 
       canvas.removeMostRecentLine(); 
      } 
     }); 

異なるクラスには、加算された凝集法でありますカメ/ ArrayListの内容を変更する:

public void cohesian(ArrayList<DynamicTurtle> turtles) 
    { 
     double flockingDistanceLimit = 50; 
     double numberOfFlockers = 0; 
     double combinedX = 0; 
     double combinedY = 0; 
     double averageCombinedX; 
     double averageCombinedY; 
     //ouble moveToFlock; 
     //double turnToFlock;  
     double distanceToPotentialFlock;   

     for (DynamicTurtle t : turtles) //SCAN FOR ALL TURTLES 
     { 
      if(this.getPositionX() != t.getPositionX() && this.getPositionY() != t.getPositionY()) //MAKE SURE TURTLE ISNT SCANNING ITS SELF 
      { 
       distanceToPotentialFlock = Math.sqrt(Math.pow((this.getPositionX()-t.getPositionX()),2) + Math.pow((this.getPositionY()-this.getPositionY()),2)); //FIND DISTANCE TO TURTLE 

       System.out.println("distanceToPotentialFlock: " + distanceToPotentialFlock); //PRINT TO SCREEN HOW FAR AWAY THE TURTLE IS 

       if(distanceToPotentialFlock < flockingDistanceLimit) //MAKE SURE THE FOUND TURTLE IS WITHIN RANGE 
       { 
        combinedX = combinedX + t.getPositionX(); //FIND SUMMATION OF X POSITIONS 
        combinedY = combinedY + t.getPositionY(); //FIND SUMMATION OF Y POSITIONS 
        numberOfFlockers++; //AS A FLOCKER HAS BEEN FOUND INCREMENT THE NUMBER OF FLOCKERS     

        System.out.println("distanceToPotentialFlock: " + distanceToPotentialFlock); 
        System.out.println("numberOfFlockers: " + numberOfFlockers); 

        if(numberOfFlockers > 0) 
        {     
         averageCombinedX = (combinedX/numberOfFlockers); //FIND AVERAGE X POSITION 
         averageCombinedY = (combinedY/numberOfFlockers); //FIND AVERAGE Y POSITION 

         System.out.println("XFLOCK: " + averageCombinedX + "YFLOCK: " + averageCombinedY); 

         double angleRad = Math.atan2(averageCombinedY, averageCombinedX); 
         double angleDeg = Math.toDegrees(angleRad); 

         // place in 0,360 range 
         if(angleDeg < 0) 
         { 
          angleDeg = 360 - (-angleDeg); 
         } 

         this.turn(angleDeg); 
         this.move(10); 

        } 
       }     
      } 
     } 

私は大いに感謝します。この問題を解決するための助けになりました。よろしく、ジェームズ。

+1

Cpuldあなたは完全なエラーメッセージを投稿してください...ここで –

+0

はeorrorメッセージです: –

+0

スレッドの例外java.util.ArrayListの$ Itr.checkForComodificationで「メイン」java.util.ConcurrentModificationExceptionが (ArrayList.java:901 TurtleProgramでTurtle.cohesianでjava.util.ArrayListの$ Itr.next(ArrayList.java:851) (TurtleProgram.gameLoopでTurtle.java:69) (TurtleProgram.java:124) で) 。 (TurtleProgram.java:107) at TurtleProgram.main(TurtleProgram.java:25) 乾杯! –

答えて

0

ボタンを押すたびにメインturtlesリストに追加または削除するため、同時変更例外が発生します。あなたはJavaでEvent Dispatch Threadsを読むのに少し時間がかかるでしょう。

ボタンのクリックイベントが別のスレッドで実行され、共有変数を変更しようとしているため、実際にはマルチスレッドアプリケーションを扱っています - turtlesリストは現在スレッドセーフなデータではありません構造。

状況によってはSO queryを参照してください。したがって、ここでの解決策の1つは、CopyOnWriteArrayListのようなスレッドセーフなデータ構造を使用することです。

これは遅くなるでしょうか?あなたのアプリケーションでは、カメのリストを追加または削除するのに比べて、多くの時間が亀のリストを反復するのに費やされているので、私の推測は無理でしょう。 This SO queryは、パフォーマンスの優れた説明を提供しますCopyOnWriteArrayList

これはあなたの問題を解決するための先頭のスタートを与えます。

+0

ありがとうございました! "import java.util.concurrent.CopyOnWriteArrayList; "私はそれを非常に速く動かすことができました!よろしく、ジェームズ。 –

+0

@JamesHornsby素晴らしい!あなたの問題を解決して他の人が将来それを参照できるようにしたら、私の答えを受け入れてください:) –

関連する問題