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

标签 java multithreading concurrency java-8 java.util.concurrent

对 DTO 中 ConcurrentHashSet 的使用有点困惑。 此 DTO 一次被多个线程访问。

第一种情况

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

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

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

这能保证线程安全吗?

第二种情况

 public class LogDTO {

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

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

或者我必须使用 AtomicReference 吗?

第三种情况

 public class LogDTO {

     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 是否更好?

最佳答案

第一个案例

它不是线程安全的,ConcurrentHashMap 仅在使用 HashMap api 时提供线程安全,这意味着从 HashMap 中添加和删除内容。当改变对HashMap的引用时,它不提供线程安全性,如果你想到的话,改变对HashMap的引用与HashMap的实现方式没有关系。

第二种和第三种情况

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

关于是否使用 volatile 还是 AtomicReference 你可以阅读 this

给你讲一下: AtomicReference 具有更多功能,但使用额外的内存来提供该功能,我个人的观点是,如果您不太关心内存,请继续使用 AtomicReference,它更具可读性,并且您不知道什么时候会发现自己需要额外的功能.

关于java - 使用 ConcurrentHashSet 时的线程安全引用分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58327778/

相关文章:

java - 加载 spring xml 抛出 SAXParseException

java - java中如何从Map中读取Arraylist的值

java - 如果某个线程运行时间过长,我可以使用 executorservice 来终止它吗?

Java:尝试更改矩形位置时出现 ArrayIndexOutOfBoundsException

java - 嵌套字段类型将仅在 Elasticsearch 中作为一个文档数进行搜索

java - 在 Java 中使用同步

c++ - 使用 sleep() 时生产者消费者(使用 Monitor)代码不工作?

spring - Redis 中的并发用于分布式系统中的闪购

sql-server - 无法在快照隔离模式下使用 READPAST

mongodb - 如何在考虑并发性的情况下更新多行?