我使用一个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。那么,它怎么会导致异常呢?
发布于 2015-12-29 09:06:03
大多数集合/迭代器都不是线程安全的。您似乎在试图通过调用synchronized来绕过这一问题。如果您使用同一个监视器对象同步对集合( map)的每次访问(读和写),这并不是个坏主意。
在示例代码中,您使用this作为监视器/锁对象(引用类型为Runnable的匿名内部类的实例)。这是不合适的,因为您在其他地方操作集合时没有使用相同的对象:每次调用代码时,this都是不同的对象,并且不会传递给调用代码。
因此,要正确地执行此操作,必须同步对map的每一次访问。而且,每次都必须使用相同的同步对象(可以使用map本身)。您可能还想了解一下同步到底是如何工作的。
发布于 2015-12-29 09:21:41
迭代映射时,不能通过添加或删除映射元素来改变映射的结构。在这里,您试图从抛出ConcurrentModifactionException的映射中移除元素。在这里,您可以获得可运行对象的同步,而不是地图上的同步。下面的代码将为您提供同步映射,或者您可以使用提供的ConcurrentMap。
Collections.synchronizedMap(map)https://stackoverflow.com/questions/34507675
复制相似问题