编程语言
首页 > 编程语言> > JUC学习笔记——共享模型之内存

JUC学习笔记——共享模型之内存

作者:互联网

Java内存模型

我们首先来介绍一下Java内存模型:

JMM的主要作用如下:

JMM主要体现在三个方面:

可见性

这一小节我们来介绍可见性

可见性问题

首先我们根据一段代码来体验什么是可视性:

// 我们首先设置一个run运行条件设置为true,在线程t运行1s之后,我们在主线程修改run为false希望停下t线程

static boolean run = true;
public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(()->{
        while(run){
            // ....
        }
    });
    t.start();
    sleep(1);
    run = false; 
}

// 线程t不会如预想的停下来!

我们进行简单的分析:

  1. 初始状态, t 线程刚开始从主内存读取了 run 的值到工作内存。

  1. 因为 t 线程要频繁从主内存中读取 run 的值,JIT 编译器会将 run 的值缓存至自己工作内存中的高速缓存中,减少对主存中 run 的访问,提高效率

  1. 1 秒之后,main 线程修改了 run 的值,并同步至主存,而 t 是从自己工作内存中的高速缓存中读取这个变量 的值,结果永远是旧值

可见性解决

我们提供两种可见性的解决方法:

  1. volatile(易变关键字)
// 它可以用来修饰成员变量和静态成员变量
// 他可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取它的值,线程操作 volatile 变量都是直接操作主存

// 我们首先设置一个run运行条件设置为true,在线程t运行1s之后,我们在主线程修改run为false希望停下t线程

static volatile boolean run = true;
public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(()->{
        while(run){
            // ....
        }
    });
    t.start();
    sleep(1);
    run = false; 
}

// 这时程序会停止!
  1. synchronized(锁关键字)
// 我们对线程内容进行加锁处理,synchronized内部会自动封装对其主存进行查找

static Object obj = new Object();
static boolean run = true;
public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(()->{
        synchronized(obj){
                while(run){
                // ....
            }
        }
    });
    t.start();
    sleep(1);
    run = false; 
}

// 这时程序会停止!

可见性解决方法对比

我们对volatile和synchronized两种方法进行简单对比:

我们在这里介绍一下为什么synchronized能进行可见性问题解决:

标签:java,模型,内存,JMM,Memory,缓存,内存,计算机,复杂,管理计算机,指令
来源: