迭代HashMap的键时出现ConcurrentModificationException

时间:2011-07-28 05:56:11

标签: android hashmap

我有HashMapSound个对象

private HashMap<Integer, Sound> sounds;

我试图迭代以关闭所有声音。我用了 this answer创建Iterator,但我仍然获得ConcurrentModificationException,但我确信没有其他代码同时调用此代码。

public synchronized final void stopAll() {
    Iterator<Entry<Integer, Sound>> soundEntries = sounds.entrySet().iterator();
    while(soundEntries.hasNext())
    {
        Entry<Integer, Sound> s = soundEntries.next();
        s.getValue().myOnCompletionListener = null;
        s.getValue().fadeYourself();
    }
    sounds.clear();
}

我应该以什么方式重写它以防止ConcurrentModificationException发生?

这是在Sound课程内:

    private class soundFader extends AsyncTask<Sound, Void, Void>
    {
        @Override
        protected Void doInBackground(Sound... arg0) {
            arg0[0].fadeOut();
            return null;
        }
    }

    private void fadeOut()
    {
        float STEP_DOWN = (float) 0.10;
        float currentVol = myVolume;
        float targetVol = 0;
        if(isSoundEnabled())
        {
            while(currentVol > targetVol)
            {
                currentVol -= STEP_DOWN;
                mp.setVolume(currentVol, currentVol);
                try {
                    Thread.sleep(70);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        mp.setVolume(0, 0);
        onCompletion(mp);
        sounds.remove(resource);    // THIS LINE WAS MY ERROR
        mp.seekTo(0);
        nowPlaying = false;
    }

    public void fadeYourself()
    {
        soundFader fader = new soundFader();
        fader.execute(this);
    }

1 个答案:

答案 0 :(得分:0)

一个线程不允许修改Collection,而另一个线程正在迭代它。

如果只想修改值(而不是键),则无需在此处使用迭代器。

public synchronized final void stopAll() {
    for(Sound s: sounds.values())
    {
        s.myOnCompletionListener = null;
        s.fadeYourself();
    }
    sounds.clear();
}

Ninja编辑
您在迭代时从集合中删除项目。因此CoMo例外。 由于您在最后进行sounds.clear();,因此您可以删除sounds.remove(resource);行。