为了账号安全,请及时绑定邮箱和手机立即绑定

如果它不能保证对迭代器的同步访问,我们为什么要使用同步集合?

如果它不能保证对迭代器的同步访问,我们为什么要使用同步集合?

米琪卡哇伊 2022-05-25 16:17:47
例如,在下面的代码中,我们必须在进行迭代时将列表包装在同步块中。Collections.synchronizedList 是否使列表同步?如果它不提供任何便利,我们为什么要这样做?谢谢!List<Integer> list = Collections.synchronizedList( new ArrayList<>(Arrays.asList(4,3,52)));synchronized(list) {       for(int data: list)         System.out.print(data+" "); }
查看完整描述

3 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

请参阅https://docs.oracle.com/javase/tutorial/collections/implementations/wrapper.html

原因是迭代是通过对集合的多次调用来完成的,集合必须组合成一个原子操作。

另请参阅https://www.baeldung.com/java-synchronized-collections


查看完整回答
反对 回复 2022-05-25
?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

如果它不提供任何便利,我们为什么要这样做

迭代时它对您没有帮助与不提供便利不同。

所有方法 - getsizesetisEmpty- 都是同步的。这意味着他们可以看到在任何线程中进行的所有写入。

如果没有同步,则无法保证在一个线程中进行的更新对任何其他线程都是可见的,因此例如,一个线程可能看到大小为 5,而另一个线程看到大小为 6。

使列表同步的机制是使其所有方法synchronized:这实际上意味着方法的主体被包装在一个synchronized (this) { ... }块中。

该方法仍然如此iterator():那也是synchronized。但是该synchronized块在iterator()返回时完成,而不是在您完成迭代时完成。这是语言设计方式的基本限制。

所以你必须通过自己添加同步块来帮助语言。


查看完整回答
反对 回复 2022-05-25
?
慕森王

TA贡献1777条经验 获得超3个赞

Wrapper 用于从被包装的集合中同步添加和删除元素。

JavaDoc 提到迭代不同步,您需要自己同步。

 * It is imperative that the user manually synchronize on the returned
 * list when iterating over it

但是其他访问操作是线程安全的,并且建立发生在关系之前(因为它们使用synchronized)。


查看完整回答
反对 回复 2022-05-25
  • 3 回答
  • 0 关注
  • 80 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信