java多线程-volatile

2022-04-21  本文已影响0人  YiiY34
public class Demo {

    static int money = 10000;
    
    public static void main(String[] args) {
        new Girl().start();
        new Boy().start();
    }
    
}

class Boy extends Thread {
    @Override
    public void run() {
        try {
            sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Demo.money = 90000;
    }
}

class Girl extends Thread {
    @Override
    public void run() {
        while (Demo.money == 10000) {

        }
        System.out.println("财产发生变化");
    }
}

这段代码中money变量在线程中发生变化,但是Girl却没有停止循环、输出内容

分析一下
在java的内存模型中堆内存是唯一的,栈内存是线程独有的,也就是说每一个线程都有自己的线程栈,所以在上面的代码中我们在堆里面创建了一个money的共享数据,boy和girl两个线程将这个moeny在自己的线程栈中临时存储称之为变量副本,这个时候boy修改money是先修改的变量副本然后再修改的堆内的共享数据,而girl还在使用的变量副本是变更前存储的,并不是最新的。

小结
堆内存是唯一的,每一个线程都有自己的线程栈
每一个线程在使用堆里面的变量时,会先拷贝一份到线程栈中
在线程中,每一次使用变量是从栈内获取的

volatile
    /**
     * 强制线程每一次在使用变量的时候都会去堆内获取最新值
     */
    volatile static int money = 10000;

当然我们也可以使用synchronized来解决这个问题
因为synchronized代码块在运行的时候
会先清空变量副本,拷贝最新的值到变量副本中

上一篇下一篇

猜你喜欢

热点阅读