Java:为什么同步列表会出现 ConcurrentModificationException?

标签 java arraylist iterator concurrentmodification

使用这段代码:

public class SynchroApp {

    public static void main(String[] args) {

        final List<String> unsyList = new ArrayList<>();
        final List<String> syList = Collections.synchronizedList(unsyList);

        TimerTask changeList = new TimerTask() {
            boolean addElem = false;

            @Override
            public void run() {
                // add / remove elements to keep size between 2 and 9
                if (syList.size() < 2)
                    addElem = true;
                else if (syList.size() > 8)
                    addElem = false;
                if (addElem)
                    syList.add(String.valueOf(System.currentTimeMillis()));
                else
                    syList.remove(0);
            }
        };

        TimerTask reverseList = new TimerTask() {
            @Override
            public void run() {
                try {
                    for (String s : syList)
                        s = new StringBuffer(s).reverse().toString();
                } catch (Exception e) {
                    System.out.println("Exception: " + e);
                }
            }
        };

        new Timer().scheduleAtFixedRate(changeList, 0L, 30L);
        new Timer().scheduleAtFixedRate(reverseList, 0L, 20L);
    }
}

为什么我在 Iterator.next 上仍然收到一些 ConcurrentModificationException

编辑:reverseList 中列表元素的更新不起作用(如评论中所述)。此代码应按预期工作:

for (int i = 0; i < syList.size(); i++)
    syList.set(i, new StringBuffer(syList.get(i)).reverse().toString());

最佳答案

因为您在迭代列表时正在修改它。

请注意,同步列表只会使其每个方法及其迭代器的方法同步。在同步列表上迭代仍然是一个非原子操作,涉及对同步方法的多次调用。如果你想让整个迭代成为原子的,你必须明确地同步它,使用列表本身作为锁:

synchronized (syList) {
    for (String s : syList) {
        s = new StringBuffer(s).reverse().toString();
    }
}

关于Java:为什么同步列表会出现 ConcurrentModificationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23427387/

相关文章:

java - 限制 Joda 定时器不依赖于系统时间

java - 如何为自定义列着色,就像 JavaFX 中的标题一样?

java - 抓取字符串中具有相同开头但结尾和长度可变的子字符串并将其添加到数组中

java - 可能有多个 ArrayList 的 ArrayList

C++ 映射 lower_bound()

java - 组合通用边界是反模式吗?

java - 在 Eclipse 中显示图像图标不起作用

java - 数组列表为所有元素打印相同的数据

java - list 的迭代器同时实现了 Kotlin.Collection.Iterator 和 Java.util.Iterator?

javascript - 使用正则表达式仅获取一场匹配