IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java中volatile关键字 -> 正文阅读

[Java知识库]Java中volatile关键字

volatile

volatile关键字在Java面试中几乎是必考题
单例模式的双重检查模式(DCL)一般会引申到synchronized关键字和volatile关键字

volatile关键字了解吗?它保证了什么特性?用什么方式禁止指令重排的吗?

1)volatile保证了什么特性

  • 保证线程可见性(多线程环境下保证内存可见性)

    • 线程修改后的共享变量值能够及时刷新,从工作内存中刷新回主内存;
    • 其它线程能够及时的把共享变量的值从主内存中更新到自己的工作内存中;
    • Java 内存模型规定,对于多个线程共享的变量,存储在主内存当中,每个线程都有自己独立的工作内存,并且线程只能访问自己的工作内存,不可以访问其它线程的工作内存。工作内存中保存了主内存中共享变量的副本,线程要操作这些共享变量,只能通过操作工作内存中的副本来实现,操作完毕之后再同步回到主内存当中,其 JVM 模型大致如下图。
    • image-20210511121557443
  • 禁止指令重排序优化(多线程模式下禁止指令重排序优化)

    • 哪条代码需要指令重排?

      instance = new instance();

    • 使用了volatile关键字之后,重排序被禁止,所有的写操作(write)都发生在读操作(read)之前。

用什么方式禁止指令重排的吗?

内存屏障:

  1. 读屏障(Load Barrier):在读指令前插入Load Barrier,可以让高速缓存中的数据失效,强制重新从主内存加载数据,保证读取的是最新数据。

  2. 写屏障(Store Barrier):在写指令后插入Store Barrier,能让写入缓存中的最新数据更新写入主内存,保证写入的数据立刻对其他线程可见。

  • 在工作内存中,每次使用V(volatile变量)前都必须先从主内存刷新最新的值,用于保证能看见其他线程对变量V所做的修改。
  • 在工作内存中,每次修改V后都必须立刻同步回主内存中,用于保证其他线程可以看到自己对变量V所做的修改。

2)volatile导致哪条代码需要指令重排?

instance = new Singleton();  

会被编译器编译成如下JVM指令:

  1. memory = allocate(); //分配对象的内存空间
  2. ctorInstance(memory); //初始化对象
  3. instance = memory; //设置instance指向刚分配的内存空间

但是这些指令排序并非一成不变,有可能会经过JVM和CPU的优化,指令重排为如下顺序:

  1. memory = allocate(); //分配对象的内存空间
  2. instance = memory; //设置instance指向刚分配的内存空间
  3. ctorInstance(memory); //初始化对象

当线程A执行完1,3,时,instance对象还未完成初始化,但已经不再指向null。此时如果线程B抢占到CPU资源,执行 if(instance == null)的结果会是false,从而返回一个没有初始化完成的instance对象。

实例化对象实际会分为3个步骤:

  1. 分配内存空间
  2. 初始化对象
  3. 将对象指向刚分配的内存空间

但有的编译器由于性能的原因,可能会将第二步和第三步进行重排序,顺序就成了:

  1. 分配内存空间
  2. 将对象指向刚分配的内存空间
  3. 初始化对象
image-20210505162555490

使用了volatile关键字之后,重排序被禁止,所有的写操作(write)都发生在读操作(read)之前。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 20:35:37  更:2022-03-21 20:40:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:36:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码