ConcurrentModificationException в Java

edit: проблема решена, она действительно пришла из подсписка. Спасибо!

Я делаю проект о генетических алгоритмах. но у меня есть озаглавленная ошибка, и я действительно не знаю, где она происходит, поэтому мне нужна ваша помощь...

вот функция:

public synchronized void evolution(){
    //TreeSet containing the 2 fathers and children
    TreeChromosome t = new TreeChromosome();
    Chromosome father1 = selection();
    Chromosome father2;
    do{father2= selection();}
    while(father1==father2);

    t.add(father1);
    t.add(father2);


    Chromosome child1 = OperatorGen.crossRight(father1, father2);
    OperatorGen.swap(father1);

    Chromosome child2 = OperatorGen.crossLeft(father1, father2);        
    OperatorGen.swap(child2);

    t.add(fils1);
    t.add(fils2);

    // we add the best 2 in the population 
       Chromosome best1=t.pollFirst();
       genotype.add(best1);
        Chromosome best2=t.pollFirst();
       genotype.add(best2);

    //we remove the non selected chromosomes
    for (Chromosome chromo : t) {
        if (genotype.contains(chromo) && t.contains(chromo)){
            genotype.remove(chromo);
        }
    }
    genotype.updateRanks();
}

когда я запускаю это, он работает нормально, но когда я запускаю это в цикле, у меня есть исключение для OperatorGen.crossLeft... вот код этой функции:

public static Chromosome crossLeft(Chromosome father1, Chromosome father2, int joint){
    List<Ville> listFather1 = father1.getCities();
    List<Ville> listFather2 = pere2.getCities();
    //we copy the first cities of father1
    List<Ville> listChild= listPere1.subList(0, joint);
    City nextCity;
    //we add the cities of father2  
    //block where the error appears, not always at the same line

  for(int i=0;i<listFather2.size();i++){           
        nextCity=listFather2.get(i);

        if(!listChild.contains(nextCity)){
            listChild.add(nextCity);
        }
    }
    Chromosome child= new Chromosome(listChild);
    return child;
 }

Я пытался добавить синхронизацию везде, но ничего не работает... Поэтому я хотел бы знать, в чем проблема и как ее исправить? Спасибо!


person user2466062    schedule 08.06.2013    source источник
comment
Где объявлен ваш genotype-экземпляр?   -  person mfaerevaag    schedule 08.06.2013
comment
в классе, содержащем первую функцию: private static TreeChromosome genotype = new TreeChromosome();   -  person user2466062    schedule 08.06.2013
comment
Вы должны предоставить полную трассировку стека. Также укажите, к чему относятся номера строк.   -  person Marko Topolnik    schedule 08.06.2013


Ответы (2)


Вы не можете удалить из коллекции, которую вы в данный момент перебираете, если вы не используете метод Iterator.remove(), который требует, чтобы вы не использовали расширенный цикл for.

person user207421    schedule 08.06.2013
comment
Вы уверены, что это так? Он перебирает t, но удаляет из genotype, которые, насколько я понимаю, являются отдельными экземплярами. - person mfaerevaag; 08.06.2013

В вашем коде вы продолжаете повторно использовать одни и те же города, а также одни и те же списки. Когда вы используете subList, вы фактически создаете представление в старом списке ( http://docs.oracle.com/javase/7/docs/api/java/util/List.html#subList(int, int]) ). Неудивительно, что при одновременной работе со всеми этими списками возникает исключение ConcurrentModificationException.

Вы должны либо быть очень осторожными с этими списками (чтобы действительно увидеть, где что-то пойдет не так, нам, вероятно, понадобится весь исходный код). Или вы должны создать новые экземпляры списка вместо подсписка.

Кстати, то, как вы перевели примерно половину французского, сделало чтение вашего кода менее легким, а не более легким.. (отец, ребенок-филс и т. д.)

person ljgw    schedule 08.06.2013
comment
извините за это =) и спасибо, я изменю это тогда. Я действительно не понимаю, почему это работает, когда я запускаю эту функцию, но не когда я вызываю ее через какое-то время (правда), например... - person user2466062; 08.06.2013