为什么我在这个例子中得到了java.util.ConcurrentModificationException?

时间:2017-09-10 07:56:15

标签: java concurrentmodification

在下面的代码示例中,我不明白为什么foo方法抛出ConcurrentModificationException。请帮忙!

private void foo() {
        synchronized (map) {
            if (map != null && !map.isEmpty()) {
                Set<String> it = map.keySet();
                ArrayList<String> delArray = new ArrayList<>();
                for (String key : it) {
                    MapItem mapItem = map.get(key);
                    if (mapItem != null) {
                        long wakeTime = System.currentTimeMillis() - mapItem.getTimestamp();
                        if (wakeTime > MY_THRESHOLD) {
                            if (mapItem.getLock() != null) {
                                mapItem.getLock().release();
                            }
                            delArray.add(key);
                        }
                    }
                }

                if (!delArray.isEmpty()) {
                    for (String key : delArray) {
                        map.remove(key);
                    }
                }
            }
        }
    }

我在&#34;上遇到异常(String key:it){&#34;线

private static class MapItem {
        private PowerManager.WakeLock lock;
        private long timestamp;

        public MapItem(PowerManager.WakeLock lock, long timestamp) {
            this.lock = lock;
            this.timestamp = timestamp;
        }

        public PowerManager.WakeLock getLock() {
            return lock;
        }

        public long getTimestamp() {
            return timestamp;
        }
    }

2 个答案:

答案 0 :(得分:1)

您正在尝试在迭代时更改map,这是不允许的。 ConcurrentModificationException

  

如果单个线程发出一系列方法调用   违反对象的合同,对象可能抛出这个   例外。例如,如果线程直接修改集合,则   而它使用快速失败的迭代器迭代集合,   迭代器将抛出此异常

答案 1 :(得分:0)

我认为您没有把所有代码放在这里。为什么构造函数如果MapItem是WakeLockItem,那么为什么  mapItem.getLock().release();呢?如果我删除所有PowerManager.WakeLock相关代码,我可以执行它。

    private static class MapItem {
    private long timestamp;

    public MapItem(long timestamp) {
        this.timestamp = timestamp;
    }

    public long getTimestamp() {
        return timestamp;
    }
}

private Map<String, MapItem> map = new HashMap<>();

private void foo() {
    synchronized (map) {
        if (map != null && !map.isEmpty()) {
            Set<String> it = map.keySet();
            ArrayList<String> delArray = new ArrayList<>();
            for (String key : it) {
                MapItem mapItem = map.get(key);
                if (mapItem != null) {
                    long wakeTime = System.currentTimeMillis() - mapItem.getTimestamp();
                    if (wakeTime > 0) {
                        delArray.add(key);
                    }
                }
            }

            if (!delArray.isEmpty()) {
                for (String key : delArray) {
                    map.remove(key);
                }
            }
        }
    }
}