Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在HashMap中迭代时ConcurrentModificationException_Java_Android_Multithreading - Fatal编程技术网

Java 在HashMap中迭代时ConcurrentModificationException

Java 在HashMap中迭代时ConcurrentModificationException,java,android,multithreading,Java,Android,Multithreading,在遍历HashMap时,我得到了一个ConcurrentModificationException 我怎样才能解决这个问题 public void stopAllPlaying(int fadeDurationInMs) { for(PlayThread thread : threadMap.values()) { if(thread != null) { thread.fadeOut(fadeDurationInMs); }

在遍历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();
    }
}
这应该可以完成任务

必须使用相同的锁实例以相同的方式锁定threadMap的所有其他用法

注意:这不是进行同步的唯一方法

另见


您可能也会发现这一点很有帮助:

您无法锁定GUI线程,因为这会暂停所有应用程序。“淡出”听起来并不是即时的


级联两个线程:GUI线程调用中间线程,然后这个中间线程调用
stopAllPlaying
,在必要时等待锁定。中间线程可以等待任意长的时间。

您尝试过任何同步技术吗?“synchronized”关键字、锁、信号量、任何东西?请参阅我的更新答案。我猜你错过了一个用法。谢谢菲尔多-这个很好用。你知道这有多有效吗?锁定线程本身会更好,这样就不会阻塞我的UI线程吗?更有效的方法是使用一些无锁算法。我个人认为,只要锁定块足够小(LOC和执行时间),就可以使用一个相当有效的锁。至少它比使用synchronized关键字锁定整个实例更有效。我不认为thread.fadeOut是问题所在。clear()更改数据结构。因此,如果Thread2已经在该线程上迭代,而Thread1清除了它,则迭代器将抛出异常。使用锁,您可以确保它被处理一次,然后被清除。第二个线程将不会进入循环,因为threadMap当时没有元素。这两个线程很好地找到了。SynchronizedMap不会帮助您,因为它只同步单个呼叫。迭代器仍将“快速失败”。关于ConcurrentHashMap,我不确定。如果我没记错的话,它至少不会抛出异常。Docu sais“迭代器和枚举返回元素,反映迭代器/枚举创建时或创建后某个时刻哈希表的状态。它们不会抛出ConcurrentModificationException。但是,迭代器设计为一次只能由一个线程使用。”所以,你可能不会得到一个例外,而是在一个过时的状态下工作。谢谢Audruis,但我不确定我是否理解你的意思。您能提供一个代码示例吗?