【问题标题】:Is modifying an object (e.g. a HashSet) in a synchronized block equivalent to making it a synchronized object?修改同步块中的对象(例如 HashSet)是否等同于使其成为同步对象?
【发布时间】:2020-07-06 01:42:34
【问题描述】:

我知道您可以使用

获得线程安全的 HashSet
HashSet<String> mySynchronizedHashSet = Collections.synchronizedSet(new HashSet<String>());

但是,如果每次要修改它时使用传统的 HashSet 并用 synchronized 块括起来呢?

synchronized(myRegularHashSet) {
    myRegularHashSet.add(new String());
}

除了每次要安全地修改集合时记得添加synchronized 关键字的缺点之外,这两种技术是否等效?我需要同时使用两者吗?他们在性能方面如何比较?假设 HashSet 仅在已知且罕见的情况下存在并发修改的风险,您是否可以通过仅在必要时同步它来节省时间?

编辑 1:刚刚找到 this previous answer,它回答了我的一些问题(尽管不是关于性能的问题)。

编辑 2:为了解决我自己的一个问题“(我是否需要同时使用两者?”),我将引用 the Javadoc,“用户在遍历返回的集合时必须手动同步它通过迭代器、拆分器或流。”我假设这意味着在使用例如迭代器时总是需要同步块,但没有必要使用同步块同步对象。

【问题讨论】:

    标签: java synchronization hashset synchronized


    【解决方案1】:

    只要您只从同步方法或块内部访问 HashSet(并且在同一个对象上同步!),它是等价的。我更喜欢“同步”关键字,而不是集合的特殊形式(但是,我推动了变速杆)。

    在大多数情况下,当您需要同步时,尝试聪明一点并没有什么好处,因为在没有并发的情况下进行同步通常会产生开销,而这些开销会在噪音中消失。此外,同步还会影响更改的可见性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 1970-01-01
      • 2012-09-14
      相关资源
      最近更新 更多