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 boolean isStop() {
return stop;
}
public void setStop(boolean stop) {
this.stop = stop;
}
}
// 测试代码
MyRun myRun = new MyRun(false);
new Thread(myRun).start();
Thread.sleep(1000);// 等待线程执行
myRun.setStop(true);
上面这段代码 while 语句内容里注释掉和不注释会不会打印 stop.为什么?
1
iEverX 2017-08-20 05:01:00 +08:00
stop 应该加 volatile,保证主线程的修改对子线程是可见的
如果不加 volatile, 1. 注释的情况,子线程没有从主内存中同步变量,子线程的值一直是 false 没有变 2. 不注释时,println 方法内部有个 sychronized 块,会同步主内存中的数据 |
2
microhz OP @iEverX 我知道加 volatile 保证可见性肯定能终止循环,我也看了 println 的源码,的确是加了同步控制:
public void println(String x) { synchronized (this) { print(x); newLine(); } } 它加锁的是 PrintStream 对象,需要保证可见性的是 MyRun 对象的属性不是么 |
3
electric 2017-08-20 12:29:15 +08:00
一个很好的 Java 转 Python 的理由!
|
5
iEverX 2017-08-20 13:46:14 +08:00
@microhz 我之前也奇怪这点,查了好久
synchronized 会同步已失效的本地缓存,而不仅仅是其 lock 的变量 http://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.1 17.1 节 https://docs.oracle.com/javase/specs/jvms/se6/html/Threads.doc.html 8.6 节 |
6
microhz OP @iEverX 看看这篇文章吧,就是不知道讲的对不对 http://www.cnblogs.com/cookiezhi/p/5774583.html
|