有没有办法在Java中原子地修改两个或多个对象?
例如,原子地设置对象的两个字段。
已更新
根据社区规则,我删除了除最后一个问题之外的所有问题。
最佳答案
关于第一点:不,这不是线程安全的发布。考虑以下事件交错:
t1: t2:
a = new A();
a.getSomeField();
a.setSomeField(1);
换句话说,t2
能够看到部分构造的对象,并且 someField
的值在被 t2< 读取时尚未定义。/
。从技术上讲,t2 将收到的值是未定义的,如果您幸运的话,t2
将仅看到默认值(在 int
字段的情况下)通常为 0)。
对于第二点:两个线程需要在同一个对象上同步,否则您可以完全省略同步(因为它会产生相同的效果)。
第三点:是的,这是由 JVM 保证的。所有等待的线程都将被唤醒,并且它们都将在取得进展之前尝试(再次)获取锁(当然,只有一个线程可以成功,所有其他线程都必须隐式等待 - 在锁上,这一次,不在条件变量上)。
第四点:不存在“多位置”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;
}
}
关于java - Java 可以原子地修改两个或更多对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25543386/