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缓存,主线程和创建线程加载状态对象到自己的缓存,在创建时-thread call' setStatus'方法它只更新其缓存数据,主线程现在无法看到更新的数据。所以它需要同步。我理解正确吗?
答案 0 :(得分:3)
有关先发条件的规则,请参阅jls 17.4.5。
在启动线程中的任何操作之前发生启动调用。因此,新线程将在主线程上看到状态对象。
但是状态的更改并不保证对主线程可见。如果主线程加入到新线程中,那么before-before规则将适用,并且一旦新线程完成,更改将可见。如果您希望在不需要新线程完成的情况下看到更改,则可以使布尔值变为volatile或将其类型更改为 的AtomicBoolean。或者将synchronized关键字放在setter和getter上。
请注意,JVM并非要求不要将其显示,因此不需要。 Ymmv取决于jvm的实现。
所以我认为你的理解是正确的。