java并发编程小案例(十)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xhd731568849/article/details/89111149

```
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秒钟呢?

猜你喜欢

转载自blog.csdn.net/xhd731568849/article/details/89111149
今日推荐