我们什么时候(或者什么时候不这样做)在使用ListIterator时允许并发修改?

问题描述 投票:4回答:1

例如,假设有一些使用Collections#reverse(List)ListIterator操作:

var forwardItr = list.listIterator();
var reverseItr = list.listIterator(list.size());
while (forwardItr.nextIndex() < reverseItr.previousIndex()) {
  var forward = forwardItr.next();
  var reverse = reverseItr.previous();
  forwardItr.set(reverse)
  reverseItr.set(forward)
}

是否应该有一些实施从ConcurrentModificationException抛出ListIterator#set?或者更确切地说,是否存在应引起异常抛出的特定类型的修改(即“结构”)?是否暗示List的某些实现可以合理地从上述操作中抛出异常?

java concurrentmodification listiterator
1个回答
5
投票

是否应该有一些实施从ConcurrentModificationException抛出ListIterator::set

答案是可能存在。

ListListIteratorConcurrentModificationException的javadocs谈到了允许的修改条款,如果不进入允许的具体内容是不允许的。如果你看一下(比如说)ArrayList的javadoc,你会看到它表示在迭代过程中允许不会导致结构修改的变化。但是,这不适用于所有列表类型;例如在CopyOnWriteArrayList的迭代期间允许所有修改。

自定义列表类型可能会对修改施加不同的约束。

或者更确切地说,是否存在应引起异常抛出的特定类型的修改(即“结构”)?

那么ListIterator::set不是结构修改。但对于某些列表类,迭代期间的“结构”修改将导致CME。

其他(假设的)例子:

  • 如果(例如)两个迭代器处于活动状态,则可以实现不允许set操作的自定义列表类,如果发生这种情况,则抛出CME。
  • 在一个自定义列表中,这是一个其他东西的排序视图,一个打破排序的set调用可能会抛出一个CME。

可以说这些可能是一个不同的例外;例如UnsupportedOperationException。我对javadocs的解读是CME是合适的。

是否暗示List的某些实现可以合理地从上述操作中抛出异常?

是。自定义List实现可以执行各种“有趣”的事情,只要它符合ListCollection API中定义的行为即可。


问:您是否需要在代码中允许此操作?

答:IMO编写代码是合理的,因此适用于“普通”列表。不可能允许自定义列表类可能执行的所有疯狂事情。

© www.soinside.com 2019 - 2024. All rights reserved.