java - Java 可以原子地修改两个或更多对象吗?

标签 java concurrency

有没有办法在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/

相关文章:

Java 多线程 : how to wait for a method to return a valid value

Java - 航空公司预订按钮

Java:如何避免方法在循环中被调用两次

concurrency - 并发访问对象组

java - YCSB Maven 构建错误

java - java中动态创建对象

Java:游戏的并发性

concurrency - 为什么 `futures::channel::mpsc`只能通知一个发送者?

concurrency - 转到 : buffered channel sum is faster?

java - NetBeans 插件更新后所有连接上的 ConnectionRequest 错误