1

这和使用 AtomicReference 一样安全吗?

private volatile String myMember;

public void setMyMember(String s) { 
   myMember = s;
}

对比

private final AtomicReference<String> myMember = new AtomicReference<>();

public void setMyMember(String s) {
    while (true) {
        String current = myMember.get();
        if (myMember.compareAndSet(current, s))
            break;
    }
}    
4

2 回答 2

5

您的代码是“安全的”,但与AtomicReference代码的作用不同。通常,当有人试图将某些内容添加到列表或对象中并且他们想要防止具有多个线程的竞争条件时,使用AtomicReference循环。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,那就打电话吧myMember.set(...)

于 2012-08-22T16:48:18.533 回答
3

您的第一个代码片段是完全线程安全的,并且足够了,因为String它是线程安全的并且分配给变量是原子的。

第二个没有多大意义,这种结构在内部使用,例如AtomicInteger避免忽略并发环境中的分配。volatile在你的情况下很好。

于 2012-08-22T16:48:36.407 回答