Java可以自动修改两个或更多对象吗?

时间:2014-08-28 07:44:47

标签: java concurrency

有没有办法在Java中原子地修改两个或多个对象?

例如,以原子方式设置对象的两个字段。

已更新

由于社区规则,我删除了除最后一个问题以外的所有问题。

1 个答案:

答案 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;
    }
}