2017-05-24 35 views
0

我有一個項目包含一些JFrames和小點移動和模擬生物。這些應該能夠重現和死亡,因此我需要修改與所有生物的ArrayList。同步一個傳遞的ArrayList

我讀了一些關於同步的內容,雖然我沒有真正得到以下內容: 我知道您可以在創建時創建同步方法或變量。 ArrayList是在單獨的JFrame中創建的,並傳遞給「World」類。

有一個類「操作」,它處理所有的行爲,如死和複製,我也傳遞ArrayList在那裏進行修改。

也被稱爲「工具包」它處理產生的東西,如初始種羣等。「世界」類包含一個線程重繪的生物,讓他們移動每個刻度。

此外還有一個類「Paint」,它處理圖形內容並擴展另一個顯示Graphic.drawStrings的JFrame,該類還獲取ArrayList以顯示死亡的生物。

那麼如何在創建同步的同時在哪裏創建同步,以便在蜱發生時更改列表? 這些類是相當大和雜亂,如果你問代碼我會更新我的問題與其中的指定代碼。 感謝您的幫助^^

簡單的例子:

工具包:

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; 

世界:

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); 
          } 
         } 

        } 
       } 
      } 


     } 

操作:

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); 
    } 

漆:

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

請創建一個[最小,完整和可驗證示例](http://stackoverflow.com/help/mcve),它描述了您的問題。這比用單詞形容它要好得多 –

+0

如果你還沒有閱讀,你可能還想閱讀https://docs.oracle.com/javase/tutorial/uiswing/concurrency/。有可能你根本不需要處理明確的同步。 – pvg

+1

由於這是一個Swing GUI,並且你沒有提到在後臺線程中正在進行的工作,所以這裏可能很少需要同步任何東西,因爲對ArrayList的所有更改可能都會在* single *線程中進行,Swing事件線程或EDT(Event Dispatch Thread)。這就引出了一個問題:爲什麼你認爲你需要在這裏同步? –

回答

1

您可以使用類Colections提供方法public static <T> List<T> synchronizedList(List<T> list)(見API這裏)。您也可以使用Vector類,它是一個同步的ArrayList,但這是一種非常古老的方式。但是在你做任何關於併發性問題的研究之前,先了解一下你是否真的需要這樣做,因爲同步是一種非常廣泛的奢侈品。你有不同的線程同時更改你的列表嗎?看看你是否真的需要它。

+0

我想通過以下例外:線程「Thread-3」中的異常java.util.ConcurrentModificationException – ProgFroz