## 问题

public class MyRun implements Runnable {

private boolean stop;

MyRun(boolean status) {
this.stop = status;
}

@Override
public void run() {
while(!stop) {
// System.out.println("running");
}
System.out.println("stop");
}

public void setStop(boolean stop) {
this.stop = stop;
}
}

// 测试代码
MyRun myRun = new MyRun(false);
myRun.setStop(true);


• 注释的情况下，子线程没有得到stop的最新值，其工作内存中的stop一直是false，因此程序死循环。 这和预期情况一致。
• 不注释的情况下，程序会一直输出running，知道1秒后，输出stop。显然子线程获得到了stop的最新值。 这里的我就不太理解了，为什么呢？

## syncronized

println函数在jdk里的实现是这样的

public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}


JSR 133 FAQ中，有如下说法

Before we can enter a synchronized block, we acquire the monitor, which has the effect of invalidating the local processor cache so that variables will be reloaded from main memory. We will then be able to see all of the writes made visible by the previous release.

attempts to perform a lock action on that object’s monitor and does not proceed further until the lock action has successfully completed

Let T be any thread, let V be any variable, and let L be any lock. There are certain constraints on the operations performed by T with respect to V and L:
Between a lock operation by T on L and a subsequent use or store operation by T on a variable V, an assign or load operation on V must intervene; moreover, if it is a load operation, then the read operation corresponding to that load must follow the lock operation, as seen by main memory. (Less formally: a lock operation behaves as if it flushes all variables from the thread’s working memory, after which the thread must either assign them itself or load copies anew from main memory.)

## 变体

public void run() {
while(!stop) {
try {
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("stop");
}


It is important to note that neither Thread.sleep nor Thread.yield have any synchronization semantics. In particular, the compiler does not have to flush writes cached in registers out to shared memory before a call to Thread.sleep or Thread.yield, nor does the compiler have to reload values cached in registers after a call to Thread.sleep or Thread.yield.

## 总结

Java的内存模型之前看过，但是并不是非常清楚。这次前后查了好多，也有了更多的理解。 并且还有个问题并没有搞清楚，Java8的规范里，哪条规则能够明确的推导出Java6关于lock的规则。 这个就慢慢再看吧