Java 线程安全迭代解释

Java 线程安全迭代解释,java,multithreading,Java,Multithreading,我对集合.synchronizedXXX方法有一个问题,这些方法返回基础集合的同步视图 使用这些,我们必须手动同步迭代(例如),否则可能导致不确定性行为 这到底是什么意思 我发现了另一句话: 面对并发访问,用户在对返回的集合进行迭代时必须手动同步该集合。原因是迭代是通过对集合的多次调用来完成的,这些调用必须组合成单个原子操作 这就是我被困的地方。我想如果我想修改集合,我会得到一个ConcurrentModificationException。因此,我需要进行同步,以避免出现这种异常(例如,当由于

我对
集合.synchronizedXXX
方法有一个问题,这些方法返回基础集合的同步视图

使用这些,我们必须手动同步迭代(例如),否则可能导致不确定性行为

这到底是什么意思

我发现了另一句话:

面对并发访问,用户在对返回的集合进行迭代时必须手动同步该集合。原因是迭代是通过对集合的多次调用来完成的,这些调用必须组合成单个原子操作

这就是我被困的地方。我想如果我想修改集合,我会得到一个
ConcurrentModificationException
。因此,我需要进行同步,以避免出现这种异常(例如,当由于编译器进行了上下文切换而导致迭代“暂停”时)


第二个链接有望证实我的想法。“非确定性行为”这句话怎么样?它是否反映了同样的想法(迭代暂停),或者在幕后有什么新的东西?

迭代是一个长期运行的操作。
Collection.synchronizedXXX
添加的逻辑将把
Iterator
上的每个
next()
调用视为单个调用,这些调用将被
同步化,但您需要确保在完全完成迭代之前不会修改集合。这就是为什么您必须在整个迭代过程中添加
synchronized

ConcurrentModificationException
,例如由引发的,不保证引发:

请注意,无法保证迭代器的快速失效行为,因为一般来说,在存在非同步并发修改的情况下,不可能做出任何硬保证。Fail fast迭代器尽最大努力抛出ConcurrentModificationException。因此,编写依赖于此异常的正确性的程序是错误的:迭代器的快速失败行为应该只用于检测bug


迭代包括执行以下操作(直接或间接使用foreach循环):


因此,如果在对hasNext()的调用和对next()的调用之间存在上下文切换,而另一个线程从集合中删除元素,那么最终会出现不可预测的行为:迭代器告诉您存在下一个元素,而实际上没有。您不是在列表的一致快照上迭代,而是在移动的目标上迭代,在线程之间不共享的列表上不会发生异常。

我接近目标了。所以我需要了解的是fail fast并不总是很好——不能保证任何事情O.O你能告诉我这样一个例子,当它没有意识到集合已经改变时,请?你能回答吗?@Törpetestű不,因为我没有一个例子。难道你不能接受文档中所说的:它不能保证“快速失败”行为会触发吗。不一定意味着它不会,只是你不能依赖它。因此,不要指望
ConcurrentModificationException
能让您避免无保护的多线程使用集合。如果您打算进行多线程访问,请使用并发集合,因为这正是它们的用途。就这么简单。
while (iterator.hasNext()) {
    iterator.next();
}