自己写了一个程序,来测试如果在多线程中没有使用Volatile,在外部修改这个变量之后会发生什么。
很遗憾的是,并没有像网上说的那样——程序会无限循环。
public class VolatileTest {
static int flag = 0;
public static void main(String[] args) throws InterruptedException {
new Thread() {
@Override
public void run() {
while (flag == 0) {
System.out.println("我在循环啊啊啊");
}
System.out.println("知道了修改了flag");
}
}.start();
Thread.sleep(500);
flag = 60;
System.out.println("已经修改了flag");
}
}
正常情况来说,因为线程会有一个flag的副本。
在main中修改flag=60之后,之前的线程应该还是保存着旧的副本。
线程中的变量flag=0才对。应该永远不会输出“知道了修改了flag”。但是事实恰恰相反。很奇怪。难道多线程不存在副本吗?
从网上得知↓↓↓ 其实线程很可能自动刷新了本地内存
System.out.println();方法有 synchronized 修饰。
使得虚拟机很有可能刷新本地内存。然后有些错误的并发代码加了行输出做调试就看起来正常了……
所以我将循环体内的 System.out.println方法去掉。
public class VolatileTest {
static int flag = 0;
public static void main(String[] args) throws InterruptedException {
new Thread() {
@Override
public void run() {
while (flag == 0) {
}
System.out.println("知道了修改了flag");
}
}.start();
Thread.sleep(500);
flag = 60;
System.out.println("已经修改了flag");
}
}
结果成功了。
程序一直在while(flag==0)跳不出来。高兴!证明多线程是存在变量副本的。