下面这段代码是验证static的线程可见性的
public class TestStatic {
public static void main(String[] args) {
Data data = new Data();
new Thread(() -> {
System.out.println("线程启动a值为:"+data.a);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
data.change();
System.out.println("线程结束a值为:"+data.a);
}).start();
//如果读取不到最新a值这里会死循环
while (data.a==0){
// System.out.println("死循环"); //当这段代码注释掉后,很开心的可以验证,没有使用volatile确实线程不可见,但是当把这个注释解开之后神奇的事情发生了,竟然走出死循环了!!!百思不得其解
}
System.out.println("a的值改变,并且被主线程看到");
}
}
class Data{
int a = 0;
void change(){
a = 4;
}
}
再看下一张图
why???为甚??
查看其字节码
相比这两张图仅仅多了一行getstatic指令,竟然能使结果截然不同,为什么呢????
继续测试
public class TestStatic {
public static void main(String[] args) {
Data data = new Data();
new Thread(() -> {
System.out.println("线程启动a值为:"+data.a);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
data.change();
System.out.println("线程结束a值为:"+data.a);
}).start();
//如果读取不到最新a值这里会死循环
while (data.a==0){
int b = 4;//添加这行代码,结果也是处于死循环中,不能正常结束
// System.out.println("死循环");
}
System.out.println("a的值改变,并且被主线程看到");
}
}
class Data{
int a = 0;
void change(){
a = 4;
}
}
=============================================
public class TestStatic {
public static void main(String[] args) {
Data data = new Data();
new Thread(() -> {
System.out.println("线程启动a值为:"+data.a);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
data.change();
System.out.println("线程结束a值为:"+data.a);
}).start();
//如果读取不到最新a值这里会死循环
while (data.a==0){
Arrays.asList();//添加这行代码后,竟然能正常结束了,查看字节码指令,也多出来个getstatic指令,由此可以推断出,一定是这个getstatic指令的问题,但是为什么呢?不知道,还要继续研究
// System.out.println("死循环");
}
System.out.println("a的值改变,并且被主线程看到");
}
}
class Data{
int a = 0;
void change(){
a = 4;
}
}
结论:
只要在while循环中调用static方法,就会出现getstatic指令,就能够正常结束,但是我没有用volatile关键字啊,为什么能正常结束呢???应该处于死循环状态啊
有知道的吗??