Reputation: 8457
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;
}
}
Upvotes: 1
Views: 1265
Reputation: 116878
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(...)
.
Upvotes: 5
Reputation: 340733
Your first code snippet is completely thread safe and is enough because String
is thread safe and assigning to variable is atomic.
The second one doesn't make much sense, such construct is used internally e.g. in AtomicInteger
to avoid ignoring assignments in concurrent environment. volatile
is fine in your case.
Upvotes: 3