1. Java内存模型

1. 1.1. 简介

JMM就是Java内存模型(java memory model)。因为在不同的硬件生产商和不同的操作系统下,内存的访问有一定的差异,所以会造成相同的代码运行在不同的系统上会出现各种问题。所以java内存模型(JMM)屏蔽掉各种硬件和操作系统的内存访问差异,以实现让java程序在各种平台下都能达到一致的并发效果。

Java内存模型规定所有的变量都存储在主内存中,包括实例变量,静态变量,但是不包括局部变量和方法参数。每个线程都有自己的工作内存,线程的工作内存保存了该线程用到的变量和主内存的副本拷贝,线程对变量的操作都在工作内存中进行线程不能直接读写主内存中的变量

不同的线程之间也无法访问对方工作内存中的变量。线程之间变量值的传递均需要通过主内存来完成。

我们可以通过下面的图直观的了解

img

每个线程的工作内存都是独立的,线程操作数据只能在工作内存中进行,然后刷回到主存。这是 Java 内存模型定义的线程基本工作方式。

2. Volatile

package link.xiaomo.tes1;

public class LiangLiang extends Thread {
    public LiangLiang(String name) {
        super(name);
    }

    @Override
    public void run() {
        while (true) {
            if (Money.money != 100000) {
                System.out.println("结婚基金已经不是十万了");
                break;
            }
        }
    }
}
  • 露露
package link.xiaomo.tes1;

public class LULU extends Thread {
    public LULU(String name) {
        super(name);
    }

    @Override
    public void run() {

        try {
            sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Money.money = 90000;
        System.out.println("花了10000");
    }
}
  • 共享变量 money
public class Money {
    public static volatile int money = 100000;
}
  • 测试代码
    • 把共享变量money前的volatile 添加和去掉的区别
public class Demo01 {
    public static void main(String[] args) {
        LiangLiang liangLiang = new LiangLiang("liangliang");
        LULU lulu = new LULU("xiaolu");

        lulu.start();
        liangLiang.start();
    }
}

给代码加锁也可以解决问题

  • 会在锁释放的时候 抹除变量副本,这样下次再获取值的时候,就会从主内存更新数据

1665888972676

如人饮水,冷暖自知。
最后更新于 2023-08-05