我们都知道,当使用 Collections.synchronizedXXX
(例如 synchronizedSet()
)时,我们会获得底层集合的同步“ View ”。
但是,这些包装器生成方法的文档声明我们必须在使用迭代器迭代集合时显式地在集合上同步。
您选择哪个选项来解决这个问题?
我只能看到以下几种方法:
- 按照文档所述进行操作:在集合上同步
- 在调用
iterator()
之前克隆集合
- 使用一个迭代器是线程安全的集合(我只知道
CopyOnWriteArrayList
/Set)
还有一个额外的问题:使用同步 View 时 - 使用 foreach/Iterable 线程安全吗?
最佳答案
您确实已经回答了您的额外问题:不,使用增强的 for 循环不安全 - 因为它使用迭代器。
至于哪种方法最合适——这真的取决于你的上下文:
- 写入频率很低吗?如果是这样,
CopyOnWriteArrayList
可能是最合适的。 - 集合是否相当小,并且迭代很快? (即您在循环中没有做太多工作)如果是这样,同步可能会很好 - 特别是如果这种情况不经常发生(即您不会对集合有太多争用)。
- 如果您正在做大量工作并且不想阻止其他线程同时工作,那么克隆集合的成功可能是可以接受的。
关于java - 集合上的线程安全迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4517653/