是否可以直接分配volatile变量线程?像AtomicReference一样安全吗?

时间:2012-08-22 16:45:41

标签: java multithreading concurrency atomic

这与使用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;
    }
}    

2 个答案:

答案 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在你的情况下很好。