java - 列出 servlet 中的 ConcurrentModificationException

标签 java multithreading servlets concurrency

关于 ArrayList 对象的 ConcurrentModificationException 有很多问题,但我找不到问题的答案。

在我的 servlet 中,我有一个 ArrayList 作为成员对象:

List myList<Object> = new ArrayList<Object> (...);

列表必须在用户和 session 之间共享。

在 servlet 的方法之一 method1 中,我需要迭代 ArrayList 项,并最终在迭代后添加 clear 列表。这里有一个片段:

for (Object o : myList) {
    // read item o
}
myList.clear();

在另一种方法中,method2,我只是将一个新项目添加到列表中。

大多数情况下,该方法会无误地结束其工作。有时,可能由于不同用户同时调用此方法,我得到了著名的 java util.ConcurrentModificationException 异常。 我应该将我的列表定义为:

List myList = Collections.synchronizedList(new ArrayList(...));

这就足够了吗?还是我遗漏了什么?幕后是什么?当有可能并发时,第二个线程是否被容器挂起待命?

编辑:我已经添加了一些评论的答案。

最佳答案

使用同步列表不会解决您的问题。问题的核心是您正在遍历列表并同时修改它。您需要使用互斥机制(同步块(synchronized block)、锁等)来确保它们不会同时发生。详细说明,如果您从以下内容开始:

methodA() {
  iterate over list {
  }
  edit list;
}

methodB() {
  edit list;
}

如果您使用同步列表,您基本上得到的是:

methodA() {
  iterate over list {
  }
  synchronized {
    edit list;
  }
}

methodB() {
  synchronized {
    edit list;
  }
}

但你真正想要的是:

methodA() {
  synchronized {
    iterate over list {
    }
    edit list;
  }
}

methodB() {
  synchronized {
    edit list;
  }
}

关于java - 列出 servlet 中的 ConcurrentModificationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8301211/

相关文章:

java - 如何从容器内连接zabbix api?

c# - 在 c# 中作为 Windows 服务运行时,TCP/IP 套接字不从机器读取数据

java - Primefaces 组件不呈现

java - Google App Engine Java servlet 读取 JSP

linux - Bash : Adding thread-capability to this bash function, 所以它更快

java - 是否有用于 Java 应用程序服务器的 .NET 类似物?

java - 带有图像的按钮

Java Multipart/post 下载

java - 我可以从启动启动一个 Activity 并让它进入后台而不让用户看到它吗,android

linux - 用于 Linux 的混合互斥库