volatile

volatile

多线程下的变量不可见性:多个线程修改共享的成员变量,会出现一个线程修改了共享的变量值以后,另一个线程不能直接看到该线程修改后的变量的最新值

volatile修饰关键字原理

volatile修改的变量可以在多线程并发修改下,实现线程间变量的可见性

volatile不保证原子性(原子性指在一次操作或者多次操作中,要么所有的操作全部得到了执行并且不会受到任何因素的干扰而中断,要么所有的操作都不执行)

AtomicInteger count =new AtomicInteger(1);//该原子类对象在不加锁的前期下实现线程的安全运行

指令禁止重排序:volatile可以防止重排序操作

重排序:为了提高性能编译器和处理器常常会对既定的代码执行顺序进行指令从排序

重排序出现的问题:代码出现的结果有误 例如:

禁止重排序:volatile修饰变量后可以实现禁止指令从排序

volatile内存语义

happens-before:阐述内存之间的内存可见性,如果一个操作执行的结果需要另一个操作可见,那么这两个操作之间必须存在happens-before关系

规则:

  1. 程序顺序规则: 解释,一个线程中的每个操作,happens-before于该线程中的任意后续操作(
  2. 锁定规则:解释:对于一个锁的解锁,happens-before于随后对这个锁的加锁
  3. volatile:解释:对于一个volatile域的写,happens-before于任意后续对这个volatile域的读
  4. 传递性:解释:如果A happen-before B且 B happen-before C那么A happens-before C
  5. 启动规则:Thread对象的start()方法先行发生于此线程的每一个动作
  6. 中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检查到中断事件的发生
  7. 终止规则:线程中得所有操作都先行发生于对此线程的终止检测
  8. 终结规则:一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始

volatile在双重检查加锁的单例中的应用:

饿汉式单例:在获取单例对象之前对象就创建完成了

懒汉式单例:在真正需要单例的时候才创建出该对象(线程不安全,在进行对象创建时当两个线程同时访问时,可能实例返回都为空)

懒汉式(volatile双重检查模式):

public class Instance {/***双重检查机制,以及使用volatile修饰* 步骤:1.构造器私有* 2.提供一个静态变量用于存储一个单例对象* 3.提供方法进行双重检查机制返回单例对象* 4.使用volatile修饰静态的变量* 加volatile关键字的目的在于防止指令从排序*/private volatile static Instance instance;private Instance(){}public static Instance getInstance() {if (instance==null){synchronized (Instance.class){//第二次检查,判断单例对象的变量是否为空if (instance==null){instance=new Instance();
}}}
return instance;}
}

静态内部类单例:

public class Instance {private static  class  singleton { private  static final  Instance INSTANCE=new Instance();}public static Instance getInstance(){return  singleton.INSTANCE;}
}

:静态内部类是在被调用是才会被加载,加上JVM的特性,这种方式实现了线程安全的创建单例对象

对比基于volatile的双重检查锁定方案和初始化类的对比,基于类初始化的实现更加简洁,但volatile的额外优势有:除了可以对静态字段实现延迟加载初始化外,还可以对实例字段实现延迟初始化

使用场景:

1.volatile适合做多线程中的纯赋值操作,如果一个共享自变量始终只被多个线程赋值,而没有其他的操作,那么可以使用volatile来代替synchronize或者代替原子变量,因为赋值自身是有原子性的,而volatile又保证可见性,所以足够保证线程安全

2.按照volatile的可见性和禁止重排序以及happens-before规则,volatile可以作为刷新之前变量的触发器,我们可以将某个变量设置为volatile修饰,其他线程一旦发现该变量修改的值后,触发获取到的该变量之前的操作都将是最新的且可见

volatile与synchronize区别

  1. volatile只能修饰实例变量和类变量,而synchronize可以修饰方法以及代码块
  2. volatile保证数据的可见性,但不保证原子性,而synchronize是一种排他的机制
  3. volatile用于禁止指令从排序:可以解决单例双重检查对象初始化代码执行乱序问题
  4. volatile可以看做事轻量版的synchronize,volatile不保证原子性,但是如果对一个共享变量进行多个线程的赋值,而没有其他的操作,那么就可以用volatile来代替synchronize因为赋值本身是有原子性的而volatile又保证了可见性,所以就可以保证线程安全了

volatile不保证原子性,但是如果对一个共享变量进行多个线程的赋值,而没有其他的操作,那么就可以用volatile来代替synchronize因为赋值本身是有原子性的而volatile又保证了可见性,所以就可以保证线程安全了

java volatile相关推荐

  1. Java volatile关键字原理解剖

    Java volatile关键字原理解剖 文章目录 Java volatile关键字原理解剖 参考文章 前置知识 CPU缓存模型 CPU缓存行 并发编程基本概念 Java锁概念 volatile关键字 ...

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

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

  3. Java Volatile关键字可见性问题分析

    Java Volatile关键字可见性问题分析 Java 内容模型 普通变量(非Vola变量)的内存不可见性 Volatile变量的内存可见性 剩余疑惑 Java 内容模型 具体可以查看这篇文章Jav ...

  4. volite java_如何理解 JAVA volatile 关键字

    最近在重新梳理多线程,同步相关的知识点.关于 volatile 关键字阅读了好多博客文章,发现质量高适合小白的不多,最终找到一篇英文的非常通俗易懂.所以学习过程中顺手翻译下来,一方面巩固知识,一方面希 ...

  5. Java Volatile 详解

    Java Volatile 详解 Volatile:是java虚拟机提供的轻量级的同步机制.保证可见性.禁止指令重排序.不保证原子性!!! 学习Volatile之前必须了解JAVA内存模型. Java ...

  6. java volatile原理A CUP层面

    作者:知乎用户 链接:https://www.zhihu.com/question/49656589/answer/117826278 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业 ...

  7. Java Volatile keyword

    java的volatile是什么意思 我们知道,在Java中设置变量值的操作,除了long和double类型的变量外都是原子操作,也就是说,对于变量值的简单读写操作没有必要进行同步. 这在JVM 1. ...

  8. 一个具体的例子学习Java volatile关键字

    相信大多数Java程序员都学习过volatile这个关键字的用法.百度百科上对volatile的定义: volatile是一个类型修饰符(type specifier),被设计用来修饰被不同线程访问和 ...

  9. java volatile 用法_java关键字volatile用法详解

    volatile关键字想必大家都不陌生,在java 5之前有着挺大的争议,在java 5之后才逐渐被大家接受,同时作为java的关键字之一,其作用自然是不可小觑的,要知道它是java.util.con ...

  10. java volatile 多线程_Java多线程之volatile

    在学习Volatile之前有必要简单了解一下物理内存模型和Java的内存模型,这样对理解Volatile大有好处. 寄存器 首先我们要知道的是所有运算操作都是在CPU的寄存器中进行的,而CUP的执行涉 ...

最新文章

  1. Require.js
  2. 关于服务器虚化的优势,服务器虚拟化优缺点总结
  3. word 通配符_word通配符技巧:HR高效办公技巧应用
  4. Python 全栈开发:python字符串切片
  5. 使用async await 封装 axios
  6. 关于 IntelliJ IDEA 的Maven 版本修改
  7. Pyinstall打包多个python脚本,包含DLL文件
  8. linux的mutex状态查询命令,如何断言std :: mutex是否已锁定?
  9. 递归算法时间复杂度计算
  10. 银行软件测试工作量分析和评估方法(转)
  11. python二进制转十进制代码_python二进制转十六进制代码
  12. 第三章 进程管理笔记
  13. 17 类的成员 私有
  14. EurekaLog发送邮件问题修正
  15. HTML代码页面无法跳转为什么,html超链接不跳转 html为什么超链接不跳转页面
  16. 4. stm32启动代码分析(一)
  17. TM4C129建立FREERTOS工程
  18. 世界上最大的开源基金会 Apache 是如何运作的?
  19. 如何连接局域网_手机画面如何投屏到电视、盒子、投影仪?
  20. 踩坑之ios手机new Date(yyyy-MM-dd hh:mm:ss).getTime()返回NaN

热门文章

  1. 可微可导连续可积的关系
  2. SAP FICO 批量成本估算
  3. 雷军:你写程序有写诗一样的感觉吗?没有就做产品经理吧
  4. 虚拟机的三种网络模式
  5. 交叉编译详解 - 概念篇
  6. Android游戏源码合集(主要是AndEngine和Libgdx的)
  7. 前端css让div浮动,Web前端篇:css浮动
  8. 你用过的论文写作神工具有哪些?
  9. mysql 判断数据库时间段是否在传入的时间段周期内
  10. 西游记中神兽谛听的能力 这款小程序也有