2017-05-24 7 views
0

Ich habe ein Projekt, das einige JFrames und kleine Punkte enthält, die sich bewegen und Kreaturen simulieren. Diese sollten sich reproduzieren und sterben können, daher muss ich die ArrayList mit allen Lebewesen modifizieren.Synchronisieren einer übergebenen ArrayList

Ich lese einige Dinge über die Synchronisierung, obwohl ich nicht wirklich Folgendes erhalten: Ich weiß, dass Sie entweder synchronisierte Methoden oder Variablen erstellen können, wenn sie erstellt werden. Die ArrayList wird in einem separaten JFrame erstellt und an die Klasse "World" übergeben.

Es gibt eine Klasse "Aktionen", die alle Aktionen wie sterben und reproduzieren behandelt, ich übergeben auch die ArrayList dort zu ändern.

auch eine Klasse „Toolkit“ genannt, was Dinge wie die Ausgangspopulation usw. Die „Welt“ enthält ein Thread-Handles zu erzeugen, die Kreaturen neu zu zeichnen und sie jede Zecke bewegen zu machen.

Des Weiteren gibt es eine Klasse „Farbe“, die die Grafik Sachen Griffe und andere JFrame zur Anzeige Graphic.drawStrings erstreckt, diese Klasse bekommt auch die Arraylist die toten Kreaturen angezeigt werden soll.

Also wie und wo muss ich eine Synchronisierung erstellen, um die Liste zu ändern, während Ticks laufen? Die Klassen sind ziemlich groß und chaotisch, wenn Sie nach Code fragen, werde ich meine Frage mit dem angegebenen Code darin aktualisieren. Danke für ^^

Vereinfachtes Beispiel helfen:

Toolkit:

public static ArrayList<Creature> generateCreatures() { 
    int amount_creatures = 10; 
    ArrayList<Creature> all = new ArrayList<>(); 
     for(int i = 0; i < amount_creatures; i++) { 
      Creature creature = new Creature(id, sex, age, energy); 
      all.add(creature); 
     } 
    } 
    return all; 

Welt:

public World(ArrayList<Creature> all ...) { 
    this.all = all; 
     ... 
    startAnimation(); 
} 
private void startAnimation() { 
     Toolkit.progress("Start Animation"); 
     startDrawThread(); 
     new Thread() { 
      public void run() { 
       Toolkit.step("Animation Thread started"); 
       try { 
        int warten; 
        long last = System.currentTimeMillis(), latest; 
        int ticks_ps = World.this.ticks_ps; 
        Toolkit.step("Ticks PS : " + ticks_ps); 
        float millsStepInterval = 1000f/ticks_ps; 
        int i = 1; 

        actions = new Actions(paint, World.this); 

        for (steps = 0; steps < Integer.MAX_VALUE - ticks_ps && running; steps++) { 

         nextTick(); 

         latest = System.currentTimeMillis(); 
         warten = Math.max(Math.round(millsStepInterval * i + (last - latest)), 0); 

         if (i == ACCURACY) { 
          i = 1; 
          last = latest + warten; 
         } else 
          i++; 
         Thread.sleep(warten); 

         synchronized (World.this) { 
          if (ticks_ps != World.this.ticks_ps) { 
           ticks_ps = World.this.ticks_ps; 
           millsStepInterval = 1000f/ticks_ps; 
          } 
         } 
        } 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
        interrupt(); 
       } 
       Toolkit.step("Animation Thread finished"); 
      } 
     }.start(); 

    } 


private void nextTick() throws InterruptedException { 

     for (Creature creature : all) { 

      double moveratio = (double) (Math.random() * creature.getAge()/100); 


      if(moveratio < 5) { 
       actions.move(all, creature, size.x, size.y); 
      } 
      else { 
       actions.idle(); 
      } 


      creature.setAge(creature.getAge() + 1); 

      for(Creature creature1 : all) { 
       for(Creature creature2 : all) { 
        if(Toolkit.isNextTo(creature1, creature2)){ 
         if (creature1.getSex() != creature2.getSex()) { 
          if(creature1.getAge() > 1000 && creature2.getAge() > 1000) { 
           Creature mother = null; 
           if (creature1.getSex() == 1) { 
            mother = creature1; 
           } else if (creature2.getSex() == 1) { 
            mother = creature2; 
           } 
           actions.reproduce(mother, all); 
          } 
         } 

        } 
       } 
      } 


     } 

Aktionen:

public static void reproduce(Creature creature, ArrayList<Creature> all) { 
     int id = Toolkit.getID(all); 
     Creature baby = new Creature(id, energy, creature.getPosition(), 2, Toolkit.generateSex(), creature.getSize()); 
     all.add(baby); 
    } 

Paint:

public Paint(World world, ArrayList<Creature> all) { 
     super(); 
     this.world = world; 
     this.all = all; 
     setBackground(Color.WHITE); 
     deads = new boolean[all.size()]; //<-- THIS ONE HAS TO BE UPDATED EACH TIME THE LIST CHANGES 
    } 
+2

Erstellen Sie ein [minimales, vollständiges und verifizierbares Beispiel] (http://stackoverflow.com/help/mcve), das Ihr Problem beschreibt. Es ist weit besser als zu versuchen, es in Worten zu beschreiben –

+0

Sie möchten wahrscheinlich auch lesen https://docs.oracle.com/javase/tutorial/uiswing/concurrency/ wenn Sie noch nicht haben. Es ist möglich, dass Sie sich überhaupt nicht mit expliziter Synchronisation beschäftigen müssen. – pvg

+1

Da dies eine Swing-GUI ist und Sie nicht erwähnen, dass in einem Hintergrundthread gearbeitet wird, ist es wahrscheinlich sehr wenig notwendig, hier irgendetwas zu synchronisieren, da wahrscheinlich alle Änderungen an der ArrayList wahrscheinlich in einem * einzigen * Thread vorgenommen werden , der Swing Event Thread oder EDT (Event Dispatch Thread). Dies wirft die Frage auf: Warum denken Sie, dass Sie hier Synchronisation brauchen? –

Antwort

1

Sie Klasse verwenden können Colections die Methode bietet public static <T> List<T> synchronizedList(List<T> list) (Siehe API hier). Sie können auch die Klasse Vector verwenden, die eine synchronisierte ArrayList ist, aber das ist wirklich alt. Aber bevor Sie etwas von Gleichzeitigkeitsproblemen lesen, um zu verstehen, ob Sie das wirklich tun müssen, da Synchronisation ein sehr expansiver Luxus ist. Haben Sie verschiedene Threads, die Ihre Liste gleichzeitig ändern? Sehen Sie, wenn Sie es wirklich brauchen.

+0

Ich vermute durch die folgende Ausnahme: Ausnahme im Thread "Thread-3" java.util.ConcurrentModificationException – ProgFroz

Verwandte Themen