问题描述
我们都知道当使用 Collections.synchronizedXXX
(例如 synchronizeSet()
)时,
We all know when using Collections.synchronizedXXX
(e.g. synchronizedSet()
) we get a synchronized "view" of the underlying collection.
但是,这些包装器生成方法的文档声明,当迭代时,我们必须在集合上显式同步
However, the document of these wrapper generation methods states that we have to explicitly synchronize on the collection when iterating of the collections using an iterator.
您选择哪个选项来解决这个问题?
Which option do you choose to solve this problem?
我只能看到以下方法:
- 在调用
iterator()之前克隆集合
- 一个迭代器是线程安全的集合(我只知道
CopyOnWriteArrayList
/ Set)
- Do it as the documentation states: synchronize on the collection
- Clone the collection before calling
iterator()
- Use a collection which iterator is thread-safe (I am only aware of
CopyOnWriteArrayList
/Set)
作为一个额外的问题:当使用同步视图 - 是使用foreach / Iterable线程安全吗?
And as a bonus question: when using a synchronized view - is the use of foreach/Iterable thread-safe?
推荐答案
p>您已经回答了您的奖金问题:不,使用增强型for循环不是安全的 - 因为它使用迭代器。
You've already answered your bonus question really: no, using an enhanced for loop isn't safe - because it uses an iterator.
至于哪个是最合适的方法 - 它真的取决于你的上下文:
As for which is the most appropriate approach - it really depends on how your context:
- 写入很少吗?如果是,
CopyOnWriteArrayList
可能是最合适的。 - 收集相当小,迭代快吗? (即你在循环中没有做太多的工作)如果是这样,同步可能会很好 - 特别是如果这不会太频繁发生(即你不会有太多的争夺集合)。
- 如果你做了很多工作,并且不想阻止其他线程同时工作,克隆集合的命中可能是可以接受的。
- Are writes very infrequent? If so,
CopyOnWriteArrayList
may be most appropriate. - Is the collection reasonably small, and the iteration quick? (i.e. you're not doing much work in the loop) If so, synchronizing may well be fine - especially if this doesn't happen too often (i.e. you won't have much contention for the collection).
- If you're doing a lot of work and don't want to block other threads working at the same time, the hit of cloning the collection may well be acceptable.
这篇关于对集合的线程安全迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!