비 다중 스레드 프로그램에서 java.util.concurrentModificationException
-
08-07-2019 - |
문제
안녕 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를 사용하면 이것은 일반적으로 같은 자원에 동시에 동시에 액세스하려고 시도하는 스레드에서 발생하는 오류 인 것 같습니다. 그러나 이것이이 시스템에서 전혀 멀티 스레딩을하지 않는 것입니다.
누군가 이것이 왜 이런 일이 일어나고 있는지 설명하거나 해킹을 생각할 수 있습니까?
많은 감사 ^_ ^
해결책
기본을 수정할 수 있습니다 Collection
의 Iterator
(에 숨겨져 있습니다 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());
}
제휴하지 않습니다 StackOverflow