【问题标题】:ConcurrentModificationException when more then one users is operating on HashMap超过一个用户在 HashMap 上操作时出现 ConcurrentModificationException
【发布时间】:2012-09-23 17:43:11
【问题描述】:

我有一个 HashMap 存储 ID 和名称对。对于这张地图的每个条目,有条件地,我将把它放在另一个HashMap 中。最后,我将对第二个地图条目进行一些操作。所有这些代码都写在 JSP 文件中。

对于单用户请求,这工作正常。当多个用户一次尝试访问此文件时,只有一个请求成功,并且对其他用户产生相同的结果。

我们可以在日志中看到如下异常:

org.apache.jasper.JasperException: java.util.ConcurrentModificationException

地图就是这种格式

Map<String, String> testmap= new HashMap<String, String>();

【问题讨论】:

    标签: java multithreading jsp hashmap


    【解决方案1】:

    来自java.util.HashMap的java文档:

    这个类的所有“集合视图方法”返回的迭代器都是快速失败的:如果在迭代器创建后的任何时候对映射进行结构修改,除了通过迭代器自己的 remove 方法之外,迭代器将抛出 ConcurrentModificationException。因此,面对并发修改,迭代器会快速而干净地失败,而不是在未来不确定的时间冒任意的、非确定性的行为。

    如前所述,最简单的解决方案是同步对同时迭代/修改的Map 的访问。

    Map map = ... //the map object has to be the same for all users calling your jsp
    
    synchronized(map) {
       //do work
    }
    

    另见oracle java tutorial about concurrency

    【讨论】:

    • 解决这个问题的方法是什么
    【解决方案2】:

    如果您的地图将被多个线程同时访问和修改,请尝试使用更好的地图实现来解决您的问题:ConcurrentHashMap collection 可以为您解决问题。

    final Map<String,String> map = new ConcurrentHashMap<String,String>();
    

    如果您不能使用 Java 5:

    final Map map = Collections.synchronizedMap(new HashMap());
    

    【讨论】:

    • @Gray 感谢您为我的回答添加了一些风格。我是这里的新手。
    【解决方案3】:

    如果您在迭代集合时修改集合,您将收到该错误,无论这发生在同一个线程还是多个线程同时发生。我怀疑这是第二种情况,因为它发生在多个用户请求中。确保使用锁保护访问(可能每个地图对象一个锁)。

    【讨论】:

    • 感谢您回复我的帖子,如何用锁保护访问,您能给我一些信息吗?
    • @user1659994:基本上无论你有一个 for 循环遍历地图或添加/删除将其包装到 synchronized 块中。确保所有线程都看到相同的锁对象。
    【解决方案4】:

    那么不同的请求可能在不同的线程上运行。您必须在通用数据结构测试图上进行同步。

    有几种方法可以实现这一点。 @Tudor 建议使用锁。那将是一种可能的方式。如果这是一个练习,我建议阅读有关多线程中的同步和 Java 中的 synchronized 方法的内容。

    【讨论】:

    • “concurrenthashmap”对这个问题有帮助。
    • 在不知道完整代码的情况下很难说。我会说这是朝着正确方向迈出的一大步。但是由于您遍历资源,您需要的不仅仅是同步对资源方法的每次调用。您需要同步整个迭代,这意味着某种锁定。通过 synchronize 块或显式锁定 (docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/…)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多