【发布时间】:2015-05-02 17:35:04
【问题描述】:
此代码来自 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);
}
}
我说的对吗?
【问题讨论】:
-
如果您使 Adder 类不可变(如 BigInteger 或 String),则根本不需要任何同步,也不需要 volatile 或 AtomicReference。
-
@maraca 两种方法都是同步的。
标签: java multithreading atomicreference