有没有办法在Java中原子地修改两个或多个对象?
例如,以原子方式设置对象的两个字段。
已更新
由于社区规则,我删除了除最后一个问题以外的所有问题。
答案 0 :(得分:1)
对于数字1:否,这不是线程安全的出版物。请考虑以下事件交错:
t1: t2:
a = new A();
a.getSomeField();
a.setSomeField(1);
换句话说,t2
能够看到部分构造的对象,someField
的值在t2
读取时未定义。从技术上讲,t2将接收的值是未定义的,如果你是(非)幸运,t2
将只看到默认值(如果int
字段通常为0)。
对于数字2:两个线程都需要在同一个对象上同步,否则你可以完全省略同步(因为它会产生相同的效果)。
3号:是的,这是由JVM保证的。所有等待的线程都将被唤醒,并且它们都将尝试在它们可以取得进展之前(再次)获取锁(当然,只有一个可以在此成功,并且所有其他线程将必须隐式等待 - 在锁上,这一次,不是条件变量)。
第4名:没有“多地方”compareAndSet
。如果我需要这样的东西,我通常会用一个小帮手类来做:
class State {
final int field1;
final String field2;
State(int f1, String f2) {
this.field1 = f1;
this.field2 = f2;
}
State derive(int arg1) {
...
}
}
private final AtomicReference<State> state = new AtomicReference<>(new State(0, ""));
public void changeState(int whatever) {
for (;;) {
final State s = state.get();
final State t = s.derive(whatever);
if (state.compareAndSet(s, t)) return;
}
}