场景引入 可见性问题

先来看一张图:

上面的图,是简化版的Java内存模型,一个线程有自己的工作内存,同时还有一个共享的主内存。

线程1和线程2读取数据data时,先从主内存里加载data变量的值到工作内存,然后才可以使用那个值。

假设现在线程1修改了data变量的值为1,然后将这个修改写入到自己的工作内存。那么此时,线程1的工作内存里data的值为1,而主内存里data的值还是0。线程2的工作内存data值也是0。

这就尴尬了,线程1和线程2操作的是用一个变量data,但由于线程本地缓存的存在,导致线程1对data变量的修改,线程2不能及时看到。

这就是Java并发编程中的可见性问题当一个线程修改某个共享变量的值,其他线程是否能够立即知道这个修改。

值得注意的是,上面的Java内存模型是极其简化的,真实的情况远比上面复杂。

volatile的作用及实现原理

要解决上述可见性问题,我们可以使用volatile关键字。

在加入volatile关键字后,线程1只要修改data变量的值,就会在修改工作内存data变量值的同时,强制将修改刷新到主内存中。与此同时,线程2需要读取data变量时,先强制将主内存的值刷新到工作内存中,从而保证线程2每次读取都是最新的值。如下图:

volatile工作原理如上所述,其在JVM底层的实现原理,涉及到内存屏障相关概念。简单来说,JVM在在遇到volatile变量时,在其写操作之后插入一个store屏障,在其读操作之前插入一个load屏障。

Java volatile关键字实现原理的更多相关文章

  1. Java volatile 关键字底层实现原理解析

    本文转载自Java volatile 关键字底层实现原理解析 导语 在Java多线程并发编程中,volatile关键词扮演着重要角色,它是轻量级的synchronized,在多处理器开发中保证了共享变 ...

  2. [Java并发编程(五)] Java volatile 的实现原理

    [Java并发编程(五)] Java volatile 的实现原理 简介 在多线程并发编程中 synchronized 和 volatile 都扮演着重要的角色,volatile 是轻量级的 sync ...

  3. [Java并发编程(三)] Java volatile 关键字介绍

    [Java并发编程(三)] Java volatile 关键字介绍 摘要 Java volatile 关键字是用来标记 Java 变量,并表示变量 "存储于主内存中" .更准确的说 ...

  4. 13、Java并发性和多线程-Java Volatile关键字

    以下内容转自http://tutorials.jenkov.com/java-concurrency/volatile.html(使用谷歌翻译): Java volatile关键字用于将Java变量标 ...

  5. Java Volatile关键字(转)

    出处:  Java Volatile关键字 Java的volatile关键字用于标记一个变量“应当存储在主存”.更确切地说,每次读取volatile变量,都应该从主存读取,而不是从CPU缓存读取.每次 ...

  6. 04 volatile关键字实现原理

    volatile关键字实现原理 1.volatile关键字的语义分析 作用:让其他线程能够马上感知到某个线程多某个变量的修改 保证可见性 对共享变量的修改,其他线程能够马上感知到 保证有序性 在重排序 ...

  7. Java volatile关键字详解

    Java volatile关键字详解 volatile是java中的一个关键字,用于修饰变量.被此关键修饰的变量可以禁止对此变量操作的指令进行重排,还有保持内存的可见性. 简言之它的作用就是: 禁止指 ...

  8. 就是要你懂Java中volatile关键字实现原理

    原文地址http://www.cnblogs.com/xrq730/p/7048693.html,转载请注明出处,谢谢 前言 我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是j ...

  9. 【转】Java学习---Java中volatile关键字实现原理

    [原文]https://www.toutiao.com/i6592879392400081412/ 前言 我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是java.util.c ...

随机推荐

  1. Kubernetes 存储卷管理 PV&PVC(十)

    目录 一.emptyDir 二.hostPath 三.PV & PVC 1.NFS PersistentVolume 2.创建 PVC 3.创建 Pod 进行挂载 为了持久化保存容器的数据,可 ...

  2. pipeline的添加顺序和执行顺序

    原文链接:https://www.cnblogs.com/ruber/p/10186571.html 本文只想讨论一下pipeline的执行顺序问题,因为这个搞不明白就不知道先添加编码还是解码,是不是 ...

  3. LeetCode 43. 字符串相乘(Multiply Strings)

    43. 字符串相乘 43. Multiply Strings 题目描述 给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式. ...

  4. 【面试】C++类中的相关函数【构造,拷贝构造,析构,友元】

    构造函数:值的初始化,可带参数,无返回值,可重载,可存在多个 析构函数:释放对象内存空间,无参数,无返回值,不可重载,只能存在一个 拷贝构造函数:拷贝对象,其形参必须是引用 1.空类会默认添加哪些东西 ...

  5. 用海豚框架(DolphinPHP)实现单/多图片上传时,如何获得图片路径

    用框架实现图片上传很简单,就不多说了,然后这个框架的实现机制是这样的,我们选择图片,点击上传,他会将图片保存在uploads下,以当天时间和随机字母作为图片名,然后在返回个数字,这个数字是这个图片的i ...

  6. input和while循环——Python编程从入门到实践

    input( ) input()函数:让程序运行暂停,等待用户输入. message = input('Tell me something, and I will repeat it back to ...

  7. 47 容器(六)——HashMap

    HashMap的概念 HashMap底层实现了哈希表,这是一种非常重要的数据结构,对于以后我们理解很多技术都有帮助,例如 redis数据库的核心技术和HashMap一样,因此,非常有必要让大家理解. ...

  8. beego 读取配置

    不知道是不是坑 官方文档 https://beego.me/docs/module/config.md . 解决办法: 1 导入 config "github.com/astaxie/bee ...

  9. kotlin --- 时间戳与字符串互相转换

    直接贴代码,清晰易懂.喜欢点个赞 class Timestamp { /** * Timestamp to String * @param Timestamp * @return String */ ...

  10. int and Integer

    int和Integer的区别 1.Integer是int的包装类,int则是java的一种基本数据类型 2.Integer变量必须实例化后才能使用,而int变量不需要 3.Integer实际是对象的引 ...