并发编程系列之变量可见性问题探究
以例子的形式看看,定义一个变量,先用static修饰,在主线程修改之后,看看在新开的子线程里能被看到?
public class Example {
private static boolean flag = true;
public void testss() {
new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while (IfTest.flag) {
i++;
}
System.out.println(i);
}
}).start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
IfTest.flag = false;
System.out.println("设置flag");
}
}
执行,控制台打印:
设置flag
ps:主线程对flag变量进行修改,子线程是不能看到的,所以里面一直在循环,不能打印统计数据值。然后怎么才能让并发线程看见?
public class Example {
private static volatile boolean flag = true;
public void testss() {
new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while (IfTest.flag) {
i++;
}
System.out.println(i);
}
}).start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
IfTest.flag = false;
System.out.println("设置flag");
}
}
控制台打印:
设置flag 72071943
public class Example {
private static boolean flag = true;
public void testss() {
new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while (IfTest.flag) {
synchronized (this) {
i++;
}
}
System.out.println(i);
}
}).start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
IfTest.flag = false;
System.out.println("设置flag");
}
}
控制台打印:
设置flag 86726163
解答这个问题,需要涉及到Java的内存模型,如下所示,Java内存模型及操作规范:
原子操作:不可被中断的一个或一系列操作
图引用网上资料: