我有一个循环,如下所示:
synchronized(list) {
int objectsN = list.size();
for (int i=0; i < objectsN; i++) {
// Do stuff...
}
}
list
是此代码所在的对象的最后一个字段。
然后我在同一个对象中有一个调用list.remove(index)
的方法,它被另一个线程调用,而某个线程在无限循环中执行上面的代码列表(在单个周期之间休眠),有时它会崩溃给出 IndexOutOfBoundsException。
如何正确同步此列表?
同步 remove 语句将解决并发问题。
synchronized (list) {
list.remove(index);
}
如果使用 Java 8,则可以在定义列表和调用list.foreach(currentElement -> {// Do stuff...})
时使用Collections.synchronizedList(list)
private List<?> list;
public Constructor(list) {
this.list = Collections.synchronizedList(list);
}
public void loopingMethod() {
list.foreach(currentElement -> {// Do stuff...});
}
public void deletingMethod(int index) {
list.remove(index); // This assumes the index is within bound
}
这个想法是,如果两个方法打算更改相同的数据,则对公共对象进行锁定。 这里甚至不必同步列表对象,任何对象都可以,但循环和删除方法都应该使用它。