一个例子说清valotile关键字的作用

Posted 小艾路西里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个例子说清valotile关键字的作用相关的知识,希望对你有一定的参考价值。

一句话总结volatile:volatile的作用即是让主内存中的数据对线程可见,避免多线程下的数据不同步

下面就用一个例子来说清valotile的作用

我们先来看下例代码

public class Test {

    private static int num=0; // 定义一个静态变量num=0

    public static void main(String[] args) {
        new Thread(()->{ //开启一个线程
            while(num==0){ //如果num==0 就一直执行该线程
            }
            System.out.println(Thread.currentThread().getName()+"完成任务"); //当num的值被改变,线程的任务就结束了
        },"线程1").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        num = 1; // 改变num的值
    }
}

上述代码的意思就是,在main方法中开启一个线程,一直执行,直到num的值被改变,就结束执行

那么这时候运行该程序,会出现以下结果
在这里插入图片描述
也就是程序一直处于运行状态,说明new Thread()线程一直在执行

这时候问题就出来了,在mian方法最后改变了num的值,使num=1,为什么线程还一直在执行状态呢

这就是因为每一个线程对应了一个工作内存,num的值是存在主内存中的,所以主内存中的num是对线程不可见的,所以main线程虽然改变了num的值,但是线程1并不能察觉,下例图可清楚的说明这一点
在这里插入图片描述

可见线程1中num一直等于0

那么这时我们在num定义前加上volatile关键字

改变这一句代码,添加volatile关键字

   private static volatile int num=0;

再次运行程序
在这里插入图片描述
这时发现线程结束了执行,这就是因为valotile的修饰,使得了在主内存中的num变量对线程可见

这时线程是直接对主内存中的数据num变量进行操作,不再经过工作内存
在这里插入图片描述
看完上述的例子,相信对volatile关键字和线程内存模式有一定的理解了,下面是补充

java线程的内存模型

① 在java种,每开启一个线程,就会创建一个对应的工作内存

② 每当需要从主内存中读取数据时,就会从主内存中复制一份数据到工作内存中,且这里的数据是主内存中最新的数据

③ 线程只能对工作内存中的数据进行操作,当线程执行完毕后,才会将工作内存中的数据持久化到主内存中

在这里插入图片描述

以上是关于一个例子说清valotile关键字的作用的主要内容,如果未能解决你的问题,请参考以下文章

Java基础和JUC常见问题

java中的 validate()有啥作用

JAVA - 并发编程 - 线程安全方案

在这个 spark 代码片段中 ordering.by 是啥意思?

inline内联函数

一文说清BI报表|定义,好处,厂商及产品