当前位置: 首页 > 知识库问答 >
问题:

同步集合中的ConcurrentModificationException

长孙哲
2023-03-14

我正在使用SynChronizedCollection.contains所有面临的问题是,当我运行下面的代码时,我得到了ConvoltModiation异常

据我所知,代码应该毫无例外地终止。

public class Main {

    public static void main(String[] args) {
        List l1 = new LinkedList(), l2 = new LinkedList();
        for (int i = 0; i < 100000; i++) {
            l1.add("" + i);
        }
        for (int i = 0; i < 100000; i++) {
            l2.add("" + i);
        }
        // reverse to make the search take a little longer
        Collections.reverse(l2);
        final List sl1 = Collections.synchronizedList(l1);
        final List sl2 = Collections.synchronizedList(l2);

        new Thread() {
            public void run() {
                // synchronized (sl2) {
                sl1.containsAll(sl2);
                // }
            }
        }.start();
        new Thread() {
            public void run() {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                }
                sl2.add("3");
            }
        }.start();
    }

}

有人能帮我理解为什么我会得到这个例外吗。

共有2个答案

林运浩
2023-03-14

我检查了代码,我认为有例外,但如果当前代码

public boolean containsAll(Collection<?> coll) {
synchronized(mutex) {return c.containsAll(coll);}
        }

已更改为。。。。

public boolean containsAll(Collection<?> coll) {
synchronized(mutex) {
               synchronized(coll) {
              return c.containsAll(coll);}}
        }

然后问题就解决了。

臧彭亮
2023-03-14

按照集合的留档::同步列表

用户在遍历返回的列表时,必须手动同步该列表。

在您的示例中,当您运行sl.containsAll(sl2)时,您会遍历sl2,而不会在sl2上进行同步。诚然,这是包含所有方法的实现细节,但在javadoc中明确指出了这一点:

这个实现遍历指定的集合,依次检查迭代器返回的每个元素,看看它是否包含在这个集合中。

您可以通过在sl2上同步来解决该问题(即取消注释已注释掉的代码)。

 类似资料:
  • 我正在向我的主干集合中添加一个项目,如下所示: 我在MyCollection中覆盖了同步,如下所示: 但是,似乎在add之后不会调用sync,add成功执行并触发“add”事件。我错过什么了吗?还是这是正确的行为?

  • 我在读Java的收藏,然后我读到了这一行: "没有一个集合类是同步的,但是正如您将在本章后面看到的,可以获得同步版本。" 有人能告诉我Java中同步和非同步集合的区别吗?

  • 我已经阅读了下面的所有问题,但在文档中找不到任何描述如何同步集合并只从集合中接收更改的文档的内容。我的同步集合中有500多个文档(使用redux-saga-firebase syncCollection),但通常只有大约100个文档会改变。在任何给定的时间,甚至更少的会改变,但我目前得到所有500+文档,当即使有一个改变,这导致500+读取。不理想,会让我付出代价。 下面是我使用redux-sag

  • 我知道重载是在编译时决定的,但当我试图运行下面的示例时,它给出了我无法理解的结果 当我每次运行这个代码片段时,我都会得到“Collection”的输出,这意味着调用参数为Collection的classify方法。 请解释

  • 问题内容: 我了解像Hashtable这样的集合是同步的,但是有人可以向我解释它是 如何 工作的,在什么时候访问仅限于并​​发调用?例如,假设我使用了一些像这样的迭代器: 有人可以解释一下从不同线程中随机调用这些函数是否有陷阱吗?特别是,迭代器如何进行同步,尤其是在使用entrySet()时,似乎也需要同步?如果在循环之一进行时调用clear()会发生什么?如果removesomething()删

  • 问题内容: 我有一个带有收集类型的表。我要从表和某些列开始。我希望每个组的结果都包含一个集合,该集合包含该组中所有单个集合的独特联合。 例如, 我在寻找什么答案 我只在寻找可以插入上方“神奇的语法在这里”占位符的表达式。我知道我可以通过加入主表或以其他方式重组查询(或当然使用PL / SQL)来完成聚合。但是,我现在暂时避免这样的解决方案。 问题答案: 从我的回答改编成另一个问题。 Oracle安