1
public class Main {

    public static void main(String[] args) {
        Status status = new Status();
        new Thread(new Runnable() {
            @Override
            public void run() {
                status.setStatus(true);
            }
        }).start();
    }
}

class Status {
    boolean status = false;
    public void setStatus(boolean status) {
        this.status = status;
    }
    public boolean getStatus() {return status;}
}

如代码所示,创建线程共享主线程状态对象。我认为它不是线程安全的,由于cpu缓存,主线程和创建线程将状态对象加载到自己的缓存中,当创建线程调用'setStatus'时方法它只更新它的缓存数据,主线程现在看不到更新的数据。所以需要同步。我理解正确吗?

4

1 回答 1

3

有关发生之前的规则,请参见 jls 17.4.5。

在启动线程中的任何操作之前发生对启动的调用。所以新线程将看到在主线程上创建的状态对象。

但是不能保证对状态的更改对主线程可见。如果主线程连接到新线程,则发生之前的规则将适用,并且一旦新线程完成,更改将可见。如果您希望在不需要新线程完成的情况下看到更改,您可以使 Boolean 不稳定或将其类型更改为 AtomicBoolean。或者将 synchronized 关键字放在 setter 和 getter 上。

请注意,JVM 不需要不使其可见,只是不需要这样做。Ymmv 取决于 jvm 实现。

所以我认为你的理解是正确的。

于 2017-05-12T15:54:49.503 回答