2012-04-17 3 views
2

단일 스레드 케이스로 생각되는 ConcurrentModificationExeption이 있습니다. 또한 List를 반복하여 루프에서 수정하려고하면 예외가 발생한다는 것을 알고 있습니다. 그러므로 실제로 반복자를 사용하여 반복하고 수정합니다. 그러나 나는 예외가있다.android ArrayList의 Iterator를 사용하는 경우에도 ConcurrentModificationException이 발생합니다.

기본적으로 일부 애니메이션 관리자를 구현하고 있으며 모든 IAnimation 개체를 ArrayList에 저장합니다. addAnimation이라는 목록을 변경하는 public 메서드가 하나 있습니다. 여기에는 목록을 반복하는 또 다른 메소드 인 calculateTick이 있습니다. 두 방법 모두 동기화되었으므로 스레드 문제가 있다고 생각하지 않습니다. 앞에서 언급했듯이, 반복자를 사용하여 루프를 반복합니다. 혹시이 예외가있는 이유가 있으십니까? 여기

내 코드입니다 :

private List<IAnimation> animations = new ArrayList<IAnimation>(); 
    public synchronized void addAnimation(IAnimation animation) { 
    animations.add(animation); 
    mLooper.update(); 
    inAnimation = true; 
} 

public synchronized void calculateTick(float tpf) {  
    for (Iterator<IAnimation> iterator = animations.iterator(); iterator.hasNext();) { 
     IAnimation animation= iterator.next(); 
        boolean animateMore = animation.calculateTick(tpf); 
     if (!animateMore) {{ 
      iterator.remove(); 
     } 
    } 

} 

그리고 여기 내 예외 :

E/AndroidHarness(9546): Exception thrown in Thread[GLThread 1260,5,main] 

04-17 11 : 55 : 38.001 : E/AndroidHarness (9546) : java.util.ConcurrentModificationException 04-17 11:55:38.001 : E/AndroidHarness (9546) : java.util.ArrayList $ ArrayListIterator.remove (ArrayList.java:582) 04-17 11 : 55 : 38.001 : E/AndroidHarness (9546) : com.avaya.mco.gui.animation.AnimationManager.calculateTick (AnimationManager.java:50) 04-17 11 : 55 : 38.001 : E/AndroidHarness (9546) : com.avaya.mco.gui.jmonkey.android.MyApplication.simpleUpdate (MyApplication.java:60) 04-17 11 : 55 : 38.001 : E/AndroidHarness (9546) : at ......

+0

지금은 목록의 복사본을 반복하고 원본에서 제거해야합니다. 하지만이 경우 ArrayListIterator가 작동한다고 생각합니다. 그게 안드로이드 버그인지 궁금한가요? – trungdinhtrong

+0

뭔가 다른 사람이 목록을 읽거나 수정하고 있습니다. 코드에서 다른 일을 할 수 있도록 코드를 훑어보십시오. 이것은 구현의 버그보다 훨씬 더 가능성이 높습니다. –

+0

당신 말이 맞아요. 그 루프 안에는 결국 목록에 변화가 생길 수있는 장소가 있습니다. 슬프게도 이미 내 코드가 버그가있을 확률이 더 높다는 것을 이미 알고 있었지만 누군가 다른 코드를 다시 말하면서도 여전히 도움이되었습니다. – trungdinhtrong

답변

0

목록에서 반복되는 다른 기능이 없다고 확신합니까? 어쩌면 애니메이션을 재생할 수 있을까요? 그 문제가 해결되지 않을 경우

또한, "ConcurrentLinkedQueue를"사용해보십시오 : http://developer.android.com/reference/java/util/concurrent/ConcurrentLinkedQueue.html 은 모든 버전에서 사용할 수, 그리고 그 반복자에 대해 말한다 : "약 일관성"... 반환 된 반복자가있다 " ConcurrentModificationException을 결코 throw하지 않고, 반복자의 구축시에 존재하는 요소를 횡장하는 것을 보증 해, 구축 후의 변경을 반영 할지도 모르는 (다만 보증 할 수 있지 않는) 반복자입니다.

+0

감사합니다. 거기에 누락 된 함수가 거기에 목록을 반복합니다. 그 루프는 애니메이션을 재생하는 루프입니다. 그러나 애니메이션 중 하나의 코드에는 목록에 애니메이션을 추가 한 곳이 있습니다. 따라서 상황 자체는 루프 자체 안에 애니메이션이 목록에 추가 된 다음 iterator.remove()가 호출되어 예외가 발생합니다. ConcurrentLinkedQueue를 사용하면 예외를 해결하는 데 실제로 도움이됩니다. – trungdinhtrong

+0

그래서 컬렉션에 뭔가를 추가하는 또 다른 스레드 였지, 그렇지? –

+0

아니요, 실제로는 같은 스레드였습니다. 같은 루프에서 발생합니다. 저에게있어서 문제는 예기치 않은 장소에서 호출 트리에서 매우 깊숙이 발견되어 처음에는 전혀 볼 수 없었습니다. – trungdinhtrong

관련 문제