```
public class Test10 {
boolean running = true;
void f(){
System.out.println("f start ");
while(running){
}
System.out.println("f end");
}
public static void main(String[] args) {
Test10 t = new Test10();
new Thread(t::f,"t1").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.running = false;
}
}
```
**问:f end 能打印出来吗?**
不能。running这个变量在线程之间是不可见的。
jmm(java memory model)中规定了一块主内存。 每个线程执行过程中有一块用于存放变量的内存。(这里的内存不是严格意义上的内存,其中还包括了CPU的缓冲区。)如果某个变量没有用volatile修饰,线程第一次会从主内存中将该值读到自己的内存中,以后读写都会从他自己的内存中读写,当线程空闲的时候,会将该变量的新值刷新到主内存中。
这里有两个线程,主线程和t1线程,t1线程读到的running变量是true,之后执行while的死循环,处于很忙的状态,没空去主内存中获取最新的值,获取的一直是他自己的内存中的running值。主线程则将running设置为false就结束,此时running=false也刷新到了主内存,但是t1线程很忙,读不到这个值。
![-w671](media/15524835022701/15547314286740.jpg)
如果将程序改为volatile boolean running = true; 在主线程将running设置为false之后,会通知其他线程:“你们的running过期了,请去主内存中重新读取”。注意加了volatile并不是每次都要去主内存中读取,而是某个线程修改这个值后,会对其他线程进行缓存过期通知。
思考题:如果while循环中加入 sleep 10秒钟呢?