为什么我把run()方法里面的i++换成System.out.println("This is running...");,flag也没加volatile关键字,程序运行之后,主线程退出?按道理flag没有加volatile,主线程是无法进行修改另一个线程的本地变量。
public class VolatileTest extends Thread {
boolean flag = true;
int i = 0;
@Override
public void run() {
while (flag) {
//i++;
System.out.println("This is running...");
}
}
public static void main(String[] args) throws Exception {
VolatileTest vt = new VolatileTest();
vt.start();
Thread.sleep(1000);
vt.flag = false;
}
}
i++
, 主线程等待System.out.println
, 主线程退出System.out.println 是个synchronized方法
System.out.println
确实是同步方法,但是不太明白是怎么影响的
@joseshiang: volatile关键字是解决可见性和有序性,你的flag字段,在run方法执行的时候,因为可见性问题对于当前线程一直都是false, 而synchronized方法可以让线程刷新主内存,涉及到JMM的知识了,我的大致理解是这样的
@joseshiang: https://www.cnblogs.com/yxy-ngu/p/15686786.html 关于volatile关键字的一些理解,你可以参考下, 嘻嘻
@让我发会呆: 我验证了一下,确实是synchronized
影响的,感谢大佬
没太看懂,flag值为true当然退出
之前问题描述的不太清晰,现在我补充了运行截图
和Java的重排指令有关,你用 volatile
修饰你的 flag 字段就正常了,感兴趣可以打印一下指令看看
刚了解下,多线程下重排指令
确实有可能会出现问题,感谢!