Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当我的程序中的所有方法都同步时,我是否可能得到ConcurrentModificationException?_Java_Concurrency_Concurrentmodification - Fatal编程技术网

Java 当我的程序中的所有方法都同步时,我是否可能得到ConcurrentModificationException?

Java 当我的程序中的所有方法都同步时,我是否可能得到ConcurrentModificationException?,java,concurrency,concurrentmodification,Java,Concurrency,Concurrentmodification,我得到了一个ConcurrentModificationException,即使我使整个程序的所有方法都同步(包括静态方法和main方法) 我没有隐藏的迭代器 这怎么可能 这是什么意思 我怎样才能修好它 当您在一个集合上进行迭代,并在此期间从该集合中删除一个条目时,会出现此异常 e、 g Collection objects=newarraylist(Arrays.asList(“a”、“b”)); 用于(对象o:对象){ objects.remove(o);//引发异常 } 必须将要删除的项

我得到了一个
ConcurrentModificationException
,即使我使整个程序的所有方法都同步(包括静态方法和
main
方法)

我没有隐藏的迭代器

  • 这怎么可能
  • 这是什么意思
  • 我怎样才能修好它

  • 当您在一个集合上进行迭代,并在此期间从该集合中删除一个条目时,会出现此异常

    e、 g

    Collection objects=newarraylist(Arrays.asList(“a”、“b”));
    用于(对象o:对象){
    objects.remove(o);//引发异常
    }
    
    必须将要删除的项添加到另一个集合中,并在完成对列表的迭代后删除它们。
    否则,您将通过对象集合的迭代器()对其进行迭代,并在当前迭代器上调用remove()。

    ConcurrentModificationException与同步无关

    它与在遍历集合时修改集合有关。正如Lie Ryan指出的,完整的堆栈跟踪将帮助我们指出您是如何获得它的

    通常,要解决此问题,在遍历集合时不能修改集合本身。

    如果运行此

    List<Object> list = new ArrayList<Object>();
    for(Object obj : list)
        list.remove(obj);
    
    List List=new ArrayList();
    对于(对象对象:列表)
    列表。删除(obj);
    
    您将得到一个共修改。在迭代集合时,如果不使用适当的函数,则无法更改集合

    可以使用以下方法解决此问题:

    List<Object> list = new ArrayList<Object>();
    for(Iterator<Object> itr = list.iterator(); itr.hasNext();)
        itr.remove();
    
    List List=new ArrayList();
    for(迭代器itr=list.Iterator();itr.hasNext();)
    itr.remove();
    
    好吧,首先,如果你看到了,这是可能的:如果鸟书和鸟不同意,相信鸟

    现在,这怎么可能发生呢?在没有看到代码的情况下很难说清楚,但是异常stacktrace将指向发生的位置;你看到了什么


    一般来说,当您有并发访问时,显然会发生这种情况。当你找到它发生的地方时,问问你自己什么线程可以到达那里。

    一个同步方法会锁定它运行的对象实例

    如果对象A和B访问同一个集合,那么A#doStuff和B#doStuff是否同步并不重要,它们仍然可以并发执行

    要锁定集合,可能需要对集合本身进行锁定:方法体中的synchronized(集合)或Java5互斥锁(更好)

    (正如其他人所指出的,即使在单个线程中也可以使用ConcurrentModificationException)

  • ConcurrentModificationException
    可能是由同一线程在对集合进行迭代时操作集合引起的
  • 这意味着在迭代集合时不要更改集合,除非通过
    迭代器.remove()
    列表迭代器.add()方法
  • 见第2条
  • 的javadoc包含以下答案:

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

    解决这个问题的方法就是不要这样做


    也就是说,(正如其他人所指出的)如果需要同时迭代和修改,请使用迭代器提供的方法,而不是直接修改集合。

    完全回溯将非常有用,尽管我对它的用途有一些猜测。在对集合进行迭代时修改集合有什么不对?如何避免呢?错误在于它会损坏迭代器。因此,如果大多数迭代器检测到您在迭代过程中修改了基础集合,就会抛出此错误。它可以通过……来避免。。。。不要那样做。很抱歉,没有更多关于您所做工作的详细信息,我不能说得更具体。我的直觉是,当您在迭代器上循环并尝试删除它时,有多个迭代器在起作用。集合上的remove()搜索它,并会导致前一个迭代器无效。我猜它只是不够聪明,无法处理这个案例,所以它只是抛出了一个异常。希望其他人能更好地回答这个问题。
    List<Object> list = new ArrayList<Object>();
    for(Iterator<Object> itr = list.iterator(); itr.hasNext();)
        itr.remove();