使用ConcurrentHashSet时的线程安全引用分配

问题描述 投票:0回答:1

对DTO中ConcurrentHashSet的用法有些困惑。一次有多个线程访问此DTO。

第一种情况

 public class DonorPlanLogDTO {
      private Set<String> person = ConcurrentHashMap.newKeySet();

      public void setPerson(Set<String> person) {
       this.person = person;
      }

      public Set<String> getPerson() {
       return this.person;
      }
    }

这是否使线程安全?

第二种情况

 public class DonorPlanLogDTO {

     private volatile Set<String> person;
      public void setPerson(Set<String> person) {
       this.person = person;
      }

      public Set<String> getPerson() {
       return this.person;
      }
 }

或者我必须使用AtomicReference吗?

第三例

 public class DonorPlanLogDTO {

     private AtomicReference<Set<String>> ref = new AtAtomicReference<>();

      public void setPerson(Set<String> person) {
       this.ref.set(person);
      }

      public Set<String> getPerson() {
       return this.ref.get();
      }
 }

如果要填充一个全新的HashSet然后将其分配给现有变量,那么使用volatile更好吗?

java multithreading concurrency java-8 java.util.concurrent
1个回答
1
投票

第一种情况

这不是线程安全的,ConcurrentHashMap仅在使用HashMap api时提供线程安全,这意味着在HashMap中添加和删除内容。在您更改对HashMap的引用时,它不提供线程安全性;如果您想到的话,则对HashMap的引用更改与HashMap的实现方式无关。

第二和第三种情况

这些情况是线程安全的,在这些情况下,您更改了分配和检索HashMap引用的实现方式以允许线程安全。

关于使用volatile还是AtomicReference,您可以阅读this

为您提供tl; dr:AtomicReference具有更多功能,但使用额外的内存来提供该功能,我个人认为,如果您不关心内存,请继续使用AtomicReference,它更具可读性,并且您不知道何时会发现自己需要其他功能。

© www.soinside.com 2019 - 2024. All rights reserved.