문제

안녕 Guru의 Im이 코드로 일자리가 하나 있습니다.

public void kill(double GrowthRate, int Death)
{
    int before = population.size();
    for (PopulationMember p : population)
    {
        int[] probs = ProbablityArrayDeath(GrowthRate,Death,(int)p.fitness());
        if (probs[RandomNumberGen.nextRandomInt(0, 99)]==0)
        {
            population.remove(p);
        }
    }
    System.out.println("Intial Population: "+before+", Deaths:"+(before-          population.size())+", New Population: "+population.size());
}

프로그램을 처음 실행하면 코드를 실행하려고 할 때이 오류에 도달합니다.

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
    at java.util.HashMap$KeyIterator.next(HashMap.java:828)
    at Genetics.Population.kill(Population.java:181)
    at Genetics.Population.run(Population.java:47)
    at Control.Main.main(Main.java:35)

약간의 goggled를 사용하면 이것은 일반적으로 같은 자원에 동시에 동시에 액세스하려고 시도하는 스레드에서 발생하는 오류 인 것 같습니다. 그러나 이것이이 시스템에서 전혀 멀티 스레딩을하지 않는 것입니다.

누군가 이것이 왜 이런 일이 일어나고 있는지 설명하거나 해킹을 생각할 수 있습니까?

많은 감사 ^_ ^

도움이 되었습니까?

해결책

기본을 수정할 수 있습니다 CollectionIterator (에 숨겨져 있습니다 for-each 고리). 이를 수행하는 올바른 방법은 다음과 같습니다.

for (Iterator<PopulationMember> it = population.iterator(); it.hasNext();) {
    PopulationMemeber p = it.next();
    int[] probs = ProbablityArrayDeath(GrowthRate,Death,(int)p.fitness());
    if (probs[RandomNumberGen.nextRandomInt(0, 99)] == 0) {
        it.remove();
    }
}

다른 팁

당신은 사용할 수 없습니다 for each 컬렉션에서 물건을 제거하면 루프.
당신은 an을 사용해야합니다 Iterator 현재 항목 호출을 제거합니다 Iterator.remove.

그렇지 않으면, for-each loop이 무대 뒤에서 당신을 위해 만들어내는 기본 반복자는 컬렉션이 어떻게 바뀌는 지 이해하지 못하고, 반복하는 동안 변경되고 있음을 알려줍니다.

당신은 for 루프 아래에 숨겨진 인구에 대한 반복자가 있습니다. 반복자 작업 중에 인구에서 품목을 제거하고 있습니다. 반복 중간에 컬렉션을 변경했기 때문에 반복자는 더 이상 작동 할 수 없습니다.

멀티 스레딩과 관련이 없습니다.

해결 방법은 컬렉션을 복사 할 수 있습니다. 사본을 반복하고 원래 컬렉션에서 요소를 제거하십시오.

public void kill(double GrowthRate, int Death) {
    int before = population.size();
    Collection<PopulationMember> forIteration = new HashSet<PopulationMember>(population); 
    for (PopulationMember p : forIteration) {
        int[] probs = ProbablityArrayDeath(GrowthRate,Death,(int)p.fitness());
        if (probs[RandomNumberGen.nextRandomInt(0, 99)]==0) {
            population.remove(p);
        }
    }
    System.out.println("Intial Population: "+before+", Deaths:"+(before - population.size())+", New Population: "+population.size());

}

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top