在迭代时将项目添加到链表是否安全
Is it safe to add items to a linked list while iterating
在迭代时向 LinkedList
添加项目是否安全?
class Worker {
final LinkedList<Foo> worklist = new LinkedList<>();
public void work() {
Iterator<Foo> iterator = worklist.iterator();
while (iterator.hasNext()) {
Foo foo = iterator.next();
doSomethingWith(foo);
}
}
public void doSomethingWith(Foo foo) {
// do something with foo
// and possibly add one (or more) foo's to the worklist
if (expression) {
worklist.add(new Foo());
}
}
}
如果不是,如何以安全有效的方式实施此行为?
请注意,这不是 about a List
,而是关于 LinkedList
。如果它不安全,我会询问替代方案。
不,这不安全。以下代码将抛出 ConcurrentModificationException
:
final LinkedList<Foo> worklist = new LinkedList<>();
worklist.add(new Foo());
Iterator<Foo> iterator = worklist.iterator();
while (iterator.hasNext()) {
Foo foo = iterator.next();
worklist.add(new Foo());
}
LinkedList
does not override iterator()
and the default implementation, defined in AbstractSequentialList
is to call listIterator()
, and LinkedList
does override listIterator
.
引用 LinkedList.listIterator
的文档:
The list-iterator is fail-fast: if the list is structurally modified at any time after the Iterator is created, in any way except through the list-iterator's own remove
or add
methods, the list-iterator will throw a ConcurrentModificationException
.
你想要的是明确使用 ListIterator
, instead of an Iterator
, and use ListIterator.add
:
final LinkedList<Foo> worklist = new LinkedList<>();
worklist.add(new Foo());
ListIterator<Foo> iterator = worklist.listIterator();
while (iterator.hasNext()) {
Foo foo = iterator.next();
iterator.add(new Foo());
}
新元素插入到 return 由 next()
编辑的元素之前,因此对 next()
的后续调用不受影响。如果要将新项添加到迭代中,可以在添加元素后调用 previous()
(并忽略 return 值)以向后移动光标。
在迭代时向 LinkedList
添加项目是否安全?
class Worker {
final LinkedList<Foo> worklist = new LinkedList<>();
public void work() {
Iterator<Foo> iterator = worklist.iterator();
while (iterator.hasNext()) {
Foo foo = iterator.next();
doSomethingWith(foo);
}
}
public void doSomethingWith(Foo foo) {
// do something with foo
// and possibly add one (or more) foo's to the worklist
if (expression) {
worklist.add(new Foo());
}
}
}
如果不是,如何以安全有效的方式实施此行为?
请注意,这不是 about a List
,而是关于 LinkedList
。如果它不安全,我会询问替代方案。
不,这不安全。以下代码将抛出 ConcurrentModificationException
:
final LinkedList<Foo> worklist = new LinkedList<>();
worklist.add(new Foo());
Iterator<Foo> iterator = worklist.iterator();
while (iterator.hasNext()) {
Foo foo = iterator.next();
worklist.add(new Foo());
}
LinkedList
does not override iterator()
and the default implementation, defined in AbstractSequentialList
is to call listIterator()
, and LinkedList
does override listIterator
.
引用 LinkedList.listIterator
的文档:
The list-iterator is fail-fast: if the list is structurally modified at any time after the Iterator is created, in any way except through the list-iterator's own
remove
oradd
methods, the list-iterator will throw aConcurrentModificationException
.
你想要的是明确使用 ListIterator
, instead of an Iterator
, and use ListIterator.add
:
final LinkedList<Foo> worklist = new LinkedList<>();
worklist.add(new Foo());
ListIterator<Foo> iterator = worklist.listIterator();
while (iterator.hasNext()) {
Foo foo = iterator.next();
iterator.add(new Foo());
}
新元素插入到 return 由 next()
编辑的元素之前,因此对 next()
的后续调用不受影响。如果要将新项添加到迭代中,可以在添加元素后调用 previous()
(并忽略 return 值)以向后移动光标。