ConcurrentModificationException при переборе ключей HashMap - PullRequest
0 голосов
/ 28 июля 2011

У меня есть HashMap из Sound объектов

private HashMap<Integer, Sound> sounds;

, которые я пытаюсь повторить, чтобы отключить все звуки.Я использовал этот ответ , чтобы создать 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 голосов
/ 28 июля 2011

Недопустимо, чтобы один поток модифицировал коллекцию, пока другой поток итерирует по ней.

Если вы хотите изменить только значения (не ключи), то здесь нет необходимости использовать итераторы.

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

Редактировать ниндзя :
Вы удаляете элементы из Коллекции во время итерации. Отсюда и исключение CoMo. Поскольку вы делаете sounds.clear(); ближе к концу, вы можете удалить строку sounds.remove(resource);.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...