标签: concurrentmodification

为什么我在这个例子中没有得到java.util.ConcurrentModificationException?

注意:我知道这个Iterator#remove()方法.

在下面的代码示例中,我不明白为什么List.removein main方法抛出ConcurrentModificationException,而不是remove方法中.

public class RemoveListElementDemo {    
    private static final List<Integer> integerList;

    static {
        integerList = new ArrayList<Integer>();
        integerList.add(1);
        integerList.add(2);
        integerList.add(3);
    }

    public static void remove(Integer toRemove) {
        for(Integer integer : integerList) {
            if(integer.equals(toRemove)) {                
                integerList.remove(integer);
            }
        }
    }

    public static void main(String... args) {                
        remove(Integer.valueOf(2));

        Integer toRemove = Integer.valueOf(3);
        for(Integer integer : integerList) {
            if(integer.equals(toRemove)) {                
                integerList.remove(integer);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

java foreach list concurrentmodification

173
推荐指数
5
解决办法
27万
查看次数

ConcurrentModificationException和HashMap

我正在使用JPA持久化对象.Main对象与另一个对象具有一个拥有的One-Many关系.另一个对象存储在HashMap中.什么样的同步可以解决这个问题?它似乎发生在完全随机的时间,并且非常难以预测.这是我得到的例外:

Exception in thread "pool-1-thread-1" java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
        at java.util.HashMap$ValueIterator.next(Unknown Source)
        at org.hibernate.collection.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:555)
        at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
        at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
        at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
        at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
        at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
Run Code Online (Sandbox Code Playgroud)

java collections exception concurrentmodification

118
推荐指数
4
解决办法
14万
查看次数

在列表迭代期间从java.util.List中删除元素时抛出ConcurrentModificationException?

@Test
public void testListCur(){
    List<String> li=new ArrayList<String>();
    for(int i=0;i<10;i++){
        li.add("str"+i);
    }

    for(String st:li){
        if(st.equalsIgnoreCase("str3"))
            li.remove("str3");
    }
    System.out.println(li);
}
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,我将抛出一个ConcurrentModificationException.

看起来当我从列表中删除指定的元素时,列表不知道它的大小是否已被更改.

我想知道这是集合和删除元素的常见问题吗?

java list concurrentmodification

60
推荐指数
5
解决办法
5万
查看次数

并发修改例外

我有这段小代码,它给了我并发修改异常.我无法理解为什么我一直得到它,即使我没有看到任何同时进行的修改.

import java.util.*;

public class SomeClass {
    public static void main(String[] args) {
        List<String> s = new ArrayList<>();
        ListIterator<String> it = s.listIterator();

        for (String a : args)
            s.add(a);

        if (it.hasNext())
            String item = it.next();

        System.out.println(s);
    }
}
Run Code Online (Sandbox Code Playgroud)

java concurrentmodification

43
推荐指数
5
解决办法
7万
查看次数

带迭代器的java.util.ConcurrentModificationException

我知道如果试图通过简单的循环从集合中删除循环,我会得到这个异常:java.util.ConcurrentModificationException.但我正在使用Iterator,它仍然会产生这个异常.知道为什么以及如何解决它?

HashSet<TableRecord> tableRecords = new HashSet<>();

...

    for (Iterator<TableRecord> iterator = tableRecords.iterator(); iterator.hasNext(); ) {
        TableRecord record = iterator.next();
        if (record.getDependency() == null) {
            for (Iterator<TableRecord> dependencyIt = tableRecords.iterator(); dependencyIt.hasNext(); ) {
                TableRecord dependency = dependencyIt.next(); //Here is the line which throws this exception
                if (dependency.getDependency() != null && dependency.getDependency().getId().equals(record.getId())) {
                    tableRecords.remove(record);
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

java iterator removechild concurrentmodification

24
推荐指数
1
解决办法
3万
查看次数

Android动画中的java.util.ConcurrentModificationException

我在Android中同步代码的概念中遗漏了一些东西.

脚本

屏幕上总是绘制3个项目.每个图像都存储在ArrayList(lstGraphics)中.为此,我使用SurfaceView.一旦用户点击图像,图像就会被移除市场并且将添加新的市场.

代码示例:

AnimationHideThread

...
    @Override
        public void run() {
            Canvas c;
            while (run) {
                c = null;
                try {
                    c = panel.getHolder().lockCanvas(null);
                      synchronized (panel.getHolder()) {

                        panel.updatePhysics();
                        panel.manageAnimations();
                        panel.onDraw(c);

                    }
                } finally {
                    if (c != null) {
                        panel.getHolder().unlockCanvasAndPost(c);
                    }
                }
            }
        }    
...
Run Code Online (Sandbox Code Playgroud)

所以你可以先看看updatePhysics().这意味着我计算每个图像移动到的方向.在这里,我还将删除列表中的点击图像.之后,我检查是否需要在manageAnimations()的列表中添加一个新项目,然后最后一步绘制整个事物.

public class Panel extends SurfaceView implements SurfaceHolder.Callback {
....
 public void manageAnimations()
    {
          synchronized (this.getHolder()) {
            ...
        while (lstGraphics.size()<3) {
                lstGraphics.add(createRandomGraphic());
                }
        }
          }
    }

 @Override
    public boolean onTouchEvent(MotionEvent event) {
         synchronized (getHolder()) { …
Run Code Online (Sandbox Code Playgroud)

animation android concurrentmodification

23
推荐指数
2
解决办法
3万
查看次数

如何在没有ConcurrentModificationException的情况下使用for-each循环迭代时修改Collection?

如果我在使用for-each循环迭代它时修改Collection,它会给出ConcurrentModificationException.有没有解决方法?

java collections concurrentmodification

22
推荐指数
2
解决办法
5万
查看次数

ConcurrentHashMap中的entrySet().removeIf的行为

我想使用ConcurrentHashMap让一个线程定期从地图中删除一些项目,并使用其他线程同时从地图中放置和获取项目.

我正在使用map.entrySet().removeIf(lambda)删除线程.我想知道我可以对它的行为做出什么假设.我可以看到该removeIf方法使用迭代器来遍历地图中的元素,检查给定的条件,然后在需要时使用它们将其删除iterator.remove().

文档提供了有关ConcurrentHashMap迭代器行为的一些信息:

类似地,Iterators,Spliterators和Enumerations在迭代器/枚举的创建时或之后的某个时刻返回反映哈希表状态的元素.嘿不要抛出ConcurrentModificationException.但是,迭代器设计为一次只能由一个线程使用.

由于整个removeIf调用发生在一个线程中,我可以确定迭代器当时不被多个线程使用.我仍然想知道下面描述的事件是否可行:

  1. 地图包含映射: 'A'->0
  2. 删除线程开始执行 map.entrySet().removeIf(entry->entry.getValue()==0)
  3. 删除线程调用.iteratator()内部removeIf呼叫,并获得迭代器反映了收集的当前状态
  4. 另一个线程执行 map.put('A', 1)
  5. 删除线程仍然看到'A'->0映射(迭代器反映旧状态),因为0==0它是true,它决定从地图中删除A键.
  6. 地图现在包含'A'->1但删除线程看到旧值,0并且'A' ->1条目被删除,即使它不应该.地图是空的.

我可以想象,实施可以通过多种方式防止这种行为.例如:可能迭代器不反映put/remove操作,但总是反映值更新,或者迭代器的remove方法可能会检查整个映射(键和值)是否仍然存在于映射中,然后才调用键上的remove.我找不到任何有关这些事情的信息,我想知道是否有一些东西可以使用例安全.

java multithreading concurrenthashmap java.util.concurrent concurrentmodification

17
推荐指数
2
解决办法
6170
查看次数

Collection根据Collection的内容抛出或不抛出ConcurrentModificationException

以下Java代码ConcurrentModificationException按预期抛出:

public class Evil
{
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<String>();
        c.add("lalala");
        c.add("sososo");
        c.add("ahaaha");
        removeLalala(c);
        System.err.println(c);
    }
    private static void removeLalala(Collection<String> c) 
    {
        for (Iterator<String> i = c.iterator(); i.hasNext();) {
            String s = i.next();
            if(s.equals("lalala")) {
                c.remove(s);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是下面的示例(仅在内容中有所不同)Collection执行时没有任何异常:

public class Evil {
    public static void main(String[] args) 
    {
        Collection<String> c = new ArrayList<String>();
        c.add("lalala");
        c.add("lalala");
        removeLalala(c);
        System.err.println(c);
    }
    private static void removeLalala(Collection<String> c) {
        for (Iterator<String> i …
Run Code Online (Sandbox Code Playgroud)

java concurrentmodification

17
推荐指数
1
解决办法
1050
查看次数

为什么列表的反向子列表的List.addAll导致ConcurrentModificationException

我一直在尝试获取列表子列表,将其反转,然后将反转的列表放回起始位置。例如,假设我们拥有列表[1, 2, 3, 4, 5, 6],然后从索引2反转到索引4将得到[1, 2, 5, 4, 3, 6]

我为此编写了一些代码,但是ConcurrentModificationException每次都给出一个代码(除非startIndex == endIndex)。下面提供了一个最小的可重现示例:

int startIndex = 2;
int endIndex = 4;
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);

List<Integer> toReverse = list.subList(startIndex, endIndex+1);
Collections.reverse(toReverse);
list.removeAll(toReverse);
list.addAll(startIndex, toReverse);
Run Code Online (Sandbox Code Playgroud)

异常线程“main” java.util.ConcurrentModificationException
在java.util.ArrayList中的$ SubList.checkForComodification(来源不明)
在java.util.ArrayList的$ SubList.size(来源不明)在
java.util.AbstractCollection.toArray(来源不明)在 test.ConcurrentExample.main(ConcurrentExample.java:64)处
java.util.ArrayList.addAll(Unknown Source

错误所指的实际行是list.addAll(startIndex, toReverse);

我不确定是什么问题,因为迭代过程中似乎没有任何变化。如果有人能解释为什么会这样和/或如何解决它,将不胜感激。

java collections arraylist concurrentmodification

16
推荐指数
2
解决办法
145
查看次数