这段代码来自Fred Long的Java Concurrency Guidelines一书。我了解一组原子操作不是原子操作。所以下面的代码是不合规的。要查找代码,请查看第 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());
}
}
正确的解决方案如下所示:
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());
}
}
但我认为正确解决方案中的原子引用是多余的,因为synchronized
它保证了可见性和原子性。
所以我的解决方案看起来像这样:
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);
}
}
我对吗?