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

Java:并发修改例外

雍志文
2023-03-14

for(条目...)中出现错误循环,其中在调用dfs()之后,它将显示ConcurrentModificationException。虽然visitedOrder与foreach循环不相关,但我不知道为什么会发生这种情况。这怎么修复呢?

public TreeMap<Integer, Integer> DFS()
{
    TreeMap<Integer, Integer> stack = new TreeMap<Integer, Integer>();
    TreeMap<Integer, Integer> visitedOrder = stack;
    for(int i = 1; i < graph[0].length-1; i++)
    {
        stack.put(i, 0);
    }
    for(Entry<Integer, Integer> vertex : stack.entrySet())
    {
        if(vertex.getValue() == 0)
            dfs(vertex.getKey(), visitedOrder);
    }
    System.out.println(visitedOrder.values());
    return visitedOrder;
}

public void dfs(int vertex, TreeMap<Integer, Integer> visited)
{
    visited.put(vertex, order++);
    int currVertex = vertex;
    for(int i = vertex; i < graph[0].length-1;i++)
    {
        if(graph[vertex][i+1] == 1)
        {
            dfs(++currVertex, visited);
            break;
        }
        currVertex++;
    }
}

共有2个答案

百里业
2023-03-14

虽然visitedOrder与foreach循环不相关,但我不知道为什么会发生这种情况。

您试图在读取时修改树状图。您只是在这一行中指向这里的引用。所以它只是相同的树状图具有不同的引用名称。

    TreeMap<Integer, Integer> stack = new TreeMap<Integer, Integer>();
    TreeMap<Integer, Integer> visitedOrder = stack;
司国源
2023-03-14

下面是“Class ConcurrentModificationException”的Javadoc:

  • http://docs.oracle.com/javase/1.5.0/docs/api/Java/util/concurrentmodificationexception.html

当不允许对对象进行并发修改时,检测到并发修改的方法可能引发此异常。

例如,通常不允许一个线程在另一个线程迭代集合时修改集合。通常,在这些情况下,迭代的结果是未定义的。如果检测到此行为,一些迭代器实现(包括JRE提供的所有通用集合实现)可能会选择抛出此异常。这样做的迭代器被称为fail-fast迭代器,因为它们失败的速度快、干净利落,而不是在将来某个不确定的时间冒着任意的、不确定的行为的风险。

请注意,此异常并不总是指示对象已被另一个线程并发修改。如果单个线程发出的方法调用序列违反了对象的约定,则对象可能引发此异常。例如,如果线程在使用fail-fast迭代器迭代集合时直接修改集合,则迭代器将抛出此异常。

碰巧,这正是您正在做的:修改您在“foreach”循环中使用的结构。

解决办法

如果您相信您的设计是正确的,那么就用一个简单的for循环:代替(int i=0;i

 类似资料:
  • 问题内容: 我有这段代码,它给了我并发修改异常。即使看不到任何并发修改,我也无法理解为什么继续得到它。 问题答案: 为了避免,你应该这样编写代码: 允许你在迭代期间修改列表,但不能在创建和使用列表之间进行修改。

  • 问题内容: 我正在用Java创建一个多线程聊天。当用户u1向用户u2发送消息但未连接用户u2时,用户u1将消息发送至服务器,而用户u2一旦连接至服务器,便会收到该消息。未发送的消息将添加到ArrayList中。连接用户后,他会检查自己是否是未决邮件的收件人。如果是,则将邮件发送给他,然后将其从待处理邮件列表中删除。这是我的方法: 这就是我得到的: 我如何解决它?是因为我正在使用迭代器吗? 问题答案

  • 下面我需要帮助:我有两种方法: 第二种方法 在for循环中的方法calculatime中,我只得到第一个项目的结果,然后得到与标题相同的错误。请帮帮我,为这个案子多解释一下。

  • 问题内容: 我正在为我的大学课程使用一些代码,并从 至: 但是新方法不断给出并发修改错误。我如何解决这个问题,为什么会发生呢? 问题答案: 这是因为执行后您继续遍历该列表。 您正在同时读取和写入列表,这破坏了foreach循环下面的迭代器协定。 用 描述如下: 返回迭代中的下一个元素。 如果迭代没有更多元素,则抛出该异常。 您可以用来检查下一个元素是否可用。

  • 另一方面,如果我们这样写,就没有并发修改异常!注意,代码完全相同,除了用于比较的字符串,在第一个示例中是代码,在第二个示例中是Java 我使用的是Netbeans 8.2,Windows 7 32bit,JDK 1.8.0_131有什么问题吗?

  • 我正在阅读关于WeakHashMap的Java文档,我得到了基本概念。由于GC线程在后台运行,因此可能会出现“异常行为”,例如在迭代时出现ConcurrentModificationException等。 我不明白的是,如果默认实现没有同步,并且没有以任何方式包含锁,那么为什么不可能得到不一致的状态呢。假设你有两条线。GC线程在某个索引处删除某个键,同时,在同一索引处,用户线程在数组中插入一个键值