2016-10-15 2 views
0

this , вероятно, самый близкий к моему делу, но это тоже не помогло.Странное ConcurrentModificationException на итерации

Я получаю ConcurrentModificationException здесь:

for (Iterator<ProjectileBase> iterator = projectiles.iterator(); iterator.hasNext();) { 
     ProjectileBase proj = iterator.next(); < here 
     if (proj == null || !proj.isValid()) { 
      iterator.remove(); 
      continue; 
     } 
     if (((!proj.ignoreRange()) ? proj.lived <= proj.data.getRange() : true)){ 
      proj.lived++; 
      proj.onTick(); 
     } else { 
      MissileHitEvent event = new MissileHitEvent(proj.shooter, proj.wand, proj, false, null); 
      Bukkit.getPluginManager().callEvent(event); 
      if (!event.isCancelled()) { 
       iterator.remove(); 
       continue; 
      } else { 
       proj.lived = 0; 
      } 
     } 
    } 

Даже если я сделал, как предложил here ?

Список задается следующим образом:

private List<ProjectileBase> projectiles = new ArrayList<ProjectileBase>(); 

который происходит инициализация по строительству класса. В чем проблема?

EDIT: консоль журнала:

[10:01:58] [Craft Scheduler Thread - 3754/WARN]: Exception in thread "Craft Scheduler Thread - 3754" 
[10:01:58] [Craft Scheduler Thread - 3754/WARN]: org.apache.commons.lang.UnhandledException: Plugin MagicWands v1.0 generated an exception while executing task 247 
    at org.bukkit.craftbukkit.v1_9_R2.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:57) 
    at com.destroystokyo.paper.ServerSchedulerReportingWrapper.run(ServerSchedulerReportingWrapper.java:22) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at java.lang.Thread.run(Unknown Source) 
Caused by: java.util.ConcurrentModificationException 
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source) 
    at java.util.ArrayList$Itr.next(Unknown Source) 
    at io.jettymc.DataHolders.ProjectileManager.iterate(ProjectileManager.java:117) 
    at io.jettymc.DataHolders.ProjectileManager$1.run(ProjectileManager.java:232) 
    at org.bukkit.craftbukkit.v1_9_R2.scheduler.CraftTask.run(CraftTask.java:58) 
    at org.bukkit.craftbukkit.v1_9_R2.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:53) 
    ... 4 more 

EDIT 2: Ну, я думаю, что стоит говорить, я строю этот проект на Bukkit/Патрубок (Minecraft сервер & API) .. но Я сомневаюсь, что это причина этой ошибки?

+0

Покажите свои консольные журналы. –

+0

Добавил это. При использовании пастебина, поскольку вставку журналов ошибок здесь просто не работает. – jetp250

+0

Журналы ошибок работают нормально. Обновил ваш вопрос для вас. – Andreas

ответ

1

Чтобы помочь вам решить проблему, у вас есть прием, который может помочь.

Предполагая projectiles является единственной ссылка на ArrayList, вы можете временно заменить его неизменный список, в то время как вы итерацию, так что только Iterator может изменить список. Если какой-либо другой код пытается изменить список, произойдет исключение, которое должно сообщить вам, где это происходит, при условии, что ваша обработка ошибок не перепутана.

Пример:

List<ProjectileBase> projectilesHold = projectiles; 
projectiles = Collections.unmodifiableList(projectiles); 
try { 
    for (Iterator<ProjectileBase> iterator = projectilesHold.iterator(); iterator.hasNext();) { 
     // other code here is unchanged 
    } 
} finally { 
    projectiles = projectilesHold; 
} 

Код сохраняет изменяемый список в «держать» переменной, а затем оборачивает список, чтобы сделать его неизменяемым. Блок finally гарантирует, что модифицируемый список будет восстановлен, несмотря ни на что.

for цикла итератор был изменен, чтобы использовать изменяемый список в «держать», так что его метод remove() работает, но где-нибудь иначе projectiles поле теперь нередактируемое на время итерации.

Это только для отладки. Как только вы идентифицируете проблему и исправите ее, удалите логику еще раз.

0

Проверьте документацию ConcurrentModificationException и ArrayList

https://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html

https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html

Чтобы решить ваш вопрос, пожалуйста, проверьте следующий код.

Для примера,

import java.util.*; 

public class HelloWorld{ 

    public static void main(String []args){ 
     List<String> animals = new ArrayList<>(); 
     animals.add("Cat1"); 
     animals.add("Cat2"); 
     animals.add("Cat3"); 
     animals.add("Cat4"); 
     animals.add("Cat5"); 

     for(ListIterator<String> iterator = animals.listIterator(); iterator.hasNext();) { 
      String name = iterator.next(); 
      if (name.equals("Cat2")) { 
       iterator.remove(); 
       continue; 
      } 
      System.out.println(name); 
     } 
    } 
} 

Ура !!!

+0

Насколько я вижу, разница в том, что вы изменили Iterator на ListIterator? – jetp250

+0

Не хотел, чтобы отправить этот комментарий, извините .. Во всяком случае, я пробовал это, и он работает, конечно, но он также работал с обычным Iterator, то есть ошибки там нет. – jetp250

 Смежные вопросы

  • Нет связанных вопросов^_^