这与使用AtomicReference一样安全吗?
private volatile String myMember;
public void setMyMember(String s) {
myMember = s;
}
VS
private final AtomicReference<String> myMember = new AtomicReference<>();
public void setMyMember(String s) {
while (true) {
String current = myMember.get();
if (myMember.compareAndSet(current, s))
break;
}
}
答案 0 :(得分:5)
您的代码是“安全的”但与AtomicReference
代码不同。通常情况下,当有人试图向列表或对象添加内容时,会使用带有AtomicReference
的{{1}}循环,并且他们希望使用多个线程来防范竞争条件。
例如:
compareAndSet
在您的情况下,由于您使用的是简单的private final AtomicReference<List<String>> listRef = new AtomicReference<>();
...
while (true) {
List<String> currentList = listRef.get();
List<String> newList = new ArrayList<String>(currentList);
newList.add(stringToAdd);
// if we update the list reference, make sure we don't overwrite another one
if (listRef.compareAndSet(currentList, newList))
break;
}
对象,因此只需将其设为String
即可。做volatile
没有意义。如果您仍想使用compareAndSet
,请致电AtomicReference
。
答案 1 :(得分:3)
您的第一个代码段是完全线程安全的,因为String
是线程安全的,并且分配给变量是原子的。
第二个没有多大意义,这种结构在内部使用,例如在AtomicInteger
中,以避免忽略并发环境中的分配。 volatile
在你的情况下很好。