This code came from the book Java Concurrency Guidelines by Fred Long. I understand that a group of atomic operations is not an atomic operation. So the code below is non-compliant. To find the code, please take a look at page 23.
public class Adder {
private AtomicReference<BigInteger> first;
private AtomicReference<BigInteger> second;
public Foo(BigInteger f, BigInteger s) {
first = new AtomicReference<BigInteger>(f);
second = new AtomicReference<BigInteger>(s);
}
public void update(BigInteger f, BigInteger s) {
first.set(f);
second.set(s);
}
public BigInteger add() {
return first.get().add(second.get());
}
}
And the right solution looks like this:
final class Adder {
// ...
public synchronized void update(BigInteger f, BigInteger s){
first.set(f);
second.set(s);
}
public synchronized BigInteger add() {
return first.get().add(second.get());
}
}
But I think the atomic references in the correct solution are redundant because synchronized
guarantees both visibility and atomicity.
So my solution would look like this:
public class Addrer {
private BigInteger first;
private BigInteger second;
public Addrer(BigInteger f, BigInteger s) {
first = f;
second = s;
}
public synchronized void update(BigInteger f, BigInteger s) {
first = f;
second = s;
}
public synchronized BigInteger add() {
return first.add(second);
}
}
Am I right?