【发布时间】:2016-01-30 22:37:37
【问题描述】:
我正在尝试模拟一个程序,该程序模拟不同线程在 ArrayList 中删除和添加对象。但是,在模拟的后期,我得到了 concurrentModificationExceptions(当线程试图访问和修改同一个变量,而迭代器被用来遍历数据时)。我已经对其进行了搜索,并看到了一些关于此的主题,即我需要使用锁/同步和/或使用 ListIterators 而不是增强的 for 循环,但是,这些选项似乎都不能解决问题。到目前为止,这是我尝试做的事情:
public Object removeSomething1(){
synchronized(this){ //Also tried only putting it around the remove block
for(Object o : myList){
myList.remove(o);
return o;
}
}
}
//This is another variaton which did not yield any improved result
public Object removeSomething2(){
ListIterator<Object> iter = myList.listIterator();
While(iter.hasNext()){
Object s = iter.next();
synchronized(this){
iter.remove();
}
return s;
}
}
//After some request here is also the simple code which adds to the list
public addSomething(Object o){
myList.add(o);
}
我执行了 5 个线程,它们在它们的 run() 方法中以 500 毫秒的间隔调用这些方法(使用 Thread.sleep())。如果我增加每个线程中的睡眠计时器并在每个线程实例之间放置一个 Thread.sleep() ,问题似乎就消失了,但我希望线程(接近)同时运行而不会干扰迭代器同时引发 ConcurrentModificationException。
【问题讨论】:
-
为什么不用
for (Object o : myList) myList.remove(o);而不是myList.removeAll()? -
因为我不想删除所有对象。我希望每个线程都删除自己的对象。这只是一个更大、更实质的程序的示例代码,其中每个线程添加并随后删除它添加的对象,但如上所述,异常仅在代码的“删除部分”中引发。
-
@tomSurge 你能显示所有修改列表的代码吗?什么添加到列表中以及如何添加?顺便说一句,您发布的内容甚至没有编译。
-
请不要发布我可以看到不会编译的代码并告诉我它可以编译。如果将那里的内容复制到源文件中,则无法编译,因为并非通过该方法的每条路径都会导致
return语句。 -
一般来说,您需要移动
synchronized块以包含所有removeSomething2()。您必须同步整个迭代。
标签: java multithreading loops synchronization locking