对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更好吗?
第一种情况
这不是线程安全的,ConcurrentHashMap仅在使用HashMap api时提供线程安全,这意味着在HashMap中添加和删除内容。在您更改对HashMap的引用时,它不提供线程安全性;如果您想到的话,则对HashMap的引用更改与HashMap的实现方式无关。
第二和第三种情况
这些情况是线程安全的,在这些情况下,您更改了分配和检索HashMap引用的实现方式以允许线程安全。
关于使用volatile还是AtomicReference,您可以阅读this
为您提供tl; dr:AtomicReference具有更多功能,但使用额外的内存来提供该功能,我个人认为,如果您不关心内存,请继续使用AtomicReference,它更具可读性,并且您不知道何时会发现自己需要其他功能。