我正在使用HashMap并使用迭代器从地图中删除元素。
new Handler(SdkContext.getApplicationContext().getMainLooper()).post(new Runnable() {
@Override
public void run() {
synchronized (this) {
Iterator<Map.Entry<Placement, Aunit>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Placement, Aunit> entry = iterator.next();
entry.getValue().deInit();
iterator.remove();
}
}
}
});
但即使这段代码有时也会导致ConcurrentModificationException
。它既是线程安全的,我也使用Iterator
。
那怎么能引起异常?
答案 0 :(得分:1)
大多数集合/迭代器都不是线程安全的。
您似乎试图通过调用synchronized
来解决这个问题。如果您使用相同的监视器对象将每次访问(读取和写入)同步到您的集合(您的map
),这不是一个坏主意。
在示例代码中,您使用this
作为监视器/锁定对象(指的是类型为Runnable
的匿名内部类的实例)。这是不合适的,因为当您在其他地方操作集合时,您没有使用相同的对象:每次调用代码时,this
都是一个不同的对象,并且它没有传递给调用代码。
因此,要做到这一点,您必须同步对map
的每次访问权限。并且,您每次都必须使用相同的同步对象(您可以使用map
本身)。您可能还想了解同步的实际工作方式。
答案 1 :(得分:0)
在遍历地图时,我们无法通过添加或删除地图中的元素来更改地图的结构。在这里,您尝试从地图中删除引发ConcurrentModifactionException的元素。在这里,您可以在Runnable对象上获得同步,但不能在地图上获得。下面的代码将为您提供同步映射,或者您可以使用提供的ConcurrentMap。
Collections.synchronizedMap(map)