簡體   English   中英

通過HashMap迭代時出現ConcurrentModificationException

[英]ConcurrentModificationException while iterating through HashMap

我在通過HashMap進行迭代時收到ConcurrentModificationException

我怎樣才能解決這個問題?

public void stopAllPlaying(int fadeDurationInMs)
{
    for(PlayThread thread : threadMap.values()) {
        if(thread != null) {
            thread.fadeOut(fadeDurationInMs);
        }
    }
    threadMap.clear();
}

更新:

不幸的是,使用lock似乎並沒有解決它。 我已復制以下錯誤消息

09-06 01:05:51.366: E/AndroidRuntime(1307): FATAL EXCEPTION: main
09-06 01:05:51.366: E/AndroidRuntime(1307): java.util.ConcurrentModificationException
09-06 01:05:51.366: E/AndroidRuntime(1307):     at java.util.HashMap$HashIterator.nextEntry(HashMap.java:796)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at java.util.HashMap$ValueIterator.next(HashMap.java:828)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at com.example.myapp.AudioTrackPlayer.stopAllPlaying(AudioTrackPlayer.java:141)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at com.example.myapp.MyApp.stopAllSounds(MyApp.java:119)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at com.example.myapp.MainActivity.stopPlayback(MainActivity.java:114)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at com.example.myapp.MainActivity.onConfigurationChanged(MainActivity.java:451)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at android.app.ActivityThread.performConfigurationChanged(ActivityThread.java:3397)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at android.app.ActivityThread.handleConfigurationChanged(ActivityThread.java:3542)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1121)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at android.os.Looper.loop(Looper.java:150)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at android.app.ActivityThread.main(ActivityThread.java:4263)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at java.lang.reflect.Method.invokeNative(Native Method)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at java.lang.reflect.Method.invoke(Method.java:507)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
09-06 01:05:51.366: E/AndroidRuntime(1307):     at dalvik.system.NativeStart.main(Native Method)

更新2:

我需要將鎖添加到所有修改了Hashmap的實例上!

private final Lock lock = new ReentrantLock();
public void stopAllPlaying(int fadeDurationInMs)
{
    lock.lock();
    try{
      for(PlayThread thread : threadMap.values()) {
          if(thread != null) {
              thread.fadeOut(fadeDurationInMs);
          }
      }
      threadMap.clear();
    }
    finally{
    lock.unlock();
    }
}

這應該做的工作。

您必須使用相同的Lock實例以相同的方式鎖定 threadMap的所有其他用法。

注意:這不是進行同步的唯一方法。

另請參見http://developer.android.com/reference/java/util/concurrent/locks/Lock.html

您也可能會發現這很有幫助: http : //docs.oracle.com/javase/tutorial/essential/concurrency/sync.html

您不能鎖定GUI線程很長時間,因為這會使所有應用程序停滯不前。 “ fadeOut”聽起來不像是瞬間。

級聯兩個線程:GUI線程調用中間線程,然后該中間線程調用stopAllPlaying ,必要時等待鎖定。 中間線程可以等待任意長時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM