即使使用Iterator,ConcurrentModificationException也是如此

时间:2015-12-29 08:55:51

标签: java android concurrency hashmap

我正在使用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。 那怎么能引起异常?

2 个答案:

答案 0 :(得分:1)

大多数集合/迭代器都不是线程安全的。 您似乎试图通过调用synchronized来解决这个问题。如果您使用相同的监视器对象每次访问(读取和写入)同步到您的集合(您的map),这不是一个坏主意。

在示例代码中,您使用this作为监视器/锁定对象(指的是类型为Runnable的匿名内部类的实例)。这是不合适的,因为当您在其他地方操作集合时,您没有使用相同的对象:每次调用代码时,this都是一个不同的对象,并且它没有传递给调用代码。

因此,要做到这一点,您必须同步map的每次访问权限。并且,您每次都必须使用相同的同步对象(您可以使用map本身)。您可能还想了解同步的实际工作方式。

答案 1 :(得分:0)

在遍历地图时,我们无法通过添加或删除地图中的元素来更改地图的结构。在这里,您尝试从地图中删除引发ConcurrentModifactionException的元素。在这里,您可以在Runnable对象上获得同步,但不能在地图上获得。下面的代码将为您提供同步映射,或者您可以使用提供的ConcurrentMap。

   Collections.synchronizedMap(map)