使用ListIterator时,我们什么时候(或什么时候不)允许并发修改?

biz*_*s86 4 java concurrentmodification listiterator

例如,假设有一些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)
}
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*n C 5

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

答案是可能存在。

的javadocs ListListIteratorConcurrentModificationException不讨论允许的细节的情况下说出允许不允许的修改条款。如果查看(说)的javadocs,ArrayList您会发现它表示在迭代过程中允许不引起结构修改的更改。但是,这并不适用于所有列表类型。例如在迭代期间允许所有修改CopyOnWriteArrayList

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

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

ListIterator::set不是结构上的修改。但是对于某些列表类,迭代过程中的“结构”修改将导致CME。

其他(假设)示例:

  • 自定义列表类可以实现的是不容许set的操作,如果(比方说)两个迭代器活跃,并抛出一个CME如果发生这种情况。

  • 在自定义列表中,该列表是其他内容的排序视图, set调用中断顺序可能会引发CME。

这些可能是不同的例外,可以争论。例如UnsupportedOperationException。我的javadoc,阅读是CME 是适当的。

是否暗示某些实现List可能合理地引发上述操作的异常?

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


问:您是否需要在代码中允许这样做?

答:IMO编写代码很合理,这样它就可以用于“正常”列表。不可能允许自定义列表类可能做的所有疯狂的事情。