Search code examples
javamultithreadingconcurrencyatomic

Is a direct assignment of a volatile variable thread safe? As safe as an AtomicReference?


Is this as safe as using an 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;
    }
}    

Solution

  • Your code is "safe" but doesn't do the same thing as the AtomicReference code. Typically, the AtomicReference loop with compareAndSet is used when someone is trying to add something to a list or object and they want to protect against the race conditions with multiple threads.

    For example:

    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;
    }
    

    In your case, since you are using a simple String object, just making it volatile will be fine. There is no point in doing the compareAndSet. If you still want to use AtomicReference, then just call myMember.set(...).