详解volatile关键字和原子引用
本篇看一下Volatile关键字和原子引用。
上图就是JUC包结构,总共分成三块
(1)java.util.concurrent:并发包基础类,包括阻塞队列,线程池相关类,线程安全Map等。
(2)java.util.concurrent.atomic:原子引用相关类
(3)java.util.concurrent.locks:线程锁相关类
线程池技术在之前的讲解应该很清楚了,今天主要解析一个volatile关键字以及原子引用的相关类。这一篇文件涉及到JMM(java内存模型)的知识,之前也有讲解。
一、volatile
这个关键字,是JVM提供的轻量级的同步机制。可能在业务功能开发中很少涉及,但其是JUC包里面拥有重要地位的大哥。
首先看下理论:
(1)保证变量内存可见性:就是当前线程对某个volatile修饰的变量进行操作的话会及时通知到其它线程。比如现在的在线编辑文档,当某个人编辑了文档并保存之后,其他人会立马收到文档已被修改的通知。
(2)不保证原子性: 原子性的意思就是某个元素已经是最小的了,不可在被分割,比如现实中原子就是最小的粒子了,不可能再被分割。而映射到这边就是说某个操作不可在被分割成两个或多个操作,要么成功,要么失败。
(3)禁止指令重排:JVM为了获取最快的运行速度,会在底层一些没有先后性要求的指令进行一些指令重排的操作,在代码层面是一步一步执行,但在底层执行的时候并不是如此。比如JVM创建了一个对象有三步,创建实例对象、分配空间、将引用指向内存空间,但是第一步和第二步并没有什么关系,这个时候就可能会发生指令重排的操作。
代码示例:
(1)可见性代码验证:
当资源类变量a未加volatile关键字修饰的时候
当添加了volatile关键字修饰后:
(2)不保证原子性验证:
如果保证原子性,那么最后输出的结果应该是20000,而真实输出是19734,所以这可以 证明其不保证原子性。
JVM为了提供了可保证原子性的原子类。
二、原子类
下图就是原子类的结构图
先用AtomicInteger类是否可以保证原子性。不多说,上图片。
可以看到,用原子类AtomicInteger类是可以获取期望值的,也就是保证了原子性。
接下来看一下原子类底层是怎么样的。
上图可以看到,有三个变量,分别是value,valueOffset,unsafe。
(1)value:是volatile关键字修饰的,也就是说原子类底层也是volatile变量。
(2)valueOffset:当前变量的内存位移值。
(3)unsafe:下图可以看到,unsafe类里面都是native修饰的本地方法,是直接调用其他语言进行操作变量的。
看一下原子类的addAndGet方法为什么能实现原子性呢?
点进去会看到它调用了unsafe的getAndAddInt方法。
继续点下去会看到如下方法,里面有个compareAndSwap。
介绍一个compareAndSwap方法,简称CAS(比较并交换),其有三个值,内存值V,旧的预估值A,更新值B。只有当V和A相等的时候,才会将变量的的值修改为B,否则什么都不干。
可以看到,上述的getAndAddInt方法是个自旋锁的实现,一直调用getIntVolatile(也是本地方法)方法获取对象的最新值,获取之后就会调用CAS方法。
CAS:原称为Compare-And-Swap,比较并交换,是一条cpu的并发原语,它的功能是判断内存某个位置的值是否为预期值,如果是则更改为预期值,这个过程是原子的。
并发原语体现在调用unsafe的方法。原语是属于操作系统的范畴,原语的执行必须是联系的,也就是原子性,不会造成所谓的数据不一致的问题。(这个我也不是很懂,毕竟我不是科班出身的程序员,应该是要学操作系统才会明白)
(如果大厂面试的时候让你手写一个自旋锁,就把上述代码糊他脸上)
上述就是其保证原子性的方法,利用自旋锁和unsafe类。
说完原子类的底层,进行拓展一下:上述可以看到,原子类java只提供了基本类型的封装,例如AtomicInteger,AtomicLong等,但是工作中需要很多其他自定义的实体,也要保证原子性,该怎么办呢?
别慌,JVM还提供了原子引用类型AtomicReference,下图可见此类是一个泛型类。
下次会带大家看一下CAS导致的ABA问题。
=======================================================
我是Liusy,一个喜欢健身的程序员。
欢迎关注公众号【Liusy01】,一起交流Java技术及健身,获取更多干货。
详解volatile关键字和原子引用的更多相关文章
- 详解 volatile关键字 与 CAS算法
(请观看本人博文 -- <详解 多线程>) 目录 内存可见性问题 volatile关键字 CAS算法: 扩展 -- 乐观锁 与 悲观锁: 悲观锁: 乐观锁: 在讲解本篇博文的知识点之前,本 ...
- 详解volatile 关键字与内存可见性
先来看一个例子: public class VolatileTest { public static void main(String[] args) { T ...
- Java之static静态关键字详解|final关键字详解
前言 在Java语言中,static表示"静态"的意思,使用场景可以用来修饰成员变量和成员方法,当然也可以是静态代码块.static的主要作用在于创建独立于具体对象的域变量或者方法 ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part5:右值引用就是右值吗?
本文为第五部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part3:右值引用
本文为第三部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/4220233.html. 右值引用 如果x是任意类型,那么x&&则被称作一个 ...
- 详解JNDI的lookup资源引用java:/comp/env
ENC的概念: The application component environment is referred to as the ENC, the enterprise naming c ...
- 详解JNDI的lookup资源引用 java:/comp/env
ENC的概念: The application component environment is referred to as the ENC, the enterprise naming c ...
- 详解php中函数的引用传递和返回 (附代码)
本篇文章带大家了解一下php的引用,详细介绍一下函数的引用传递和引用返回.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助.php的引用(就是在变量或者函数.对象等前面加上&符号 ...
- Java(2)详解注释&关键字&常量&变量&标识符
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201497.html 博客主页:https://www.cnblogs.com/testero ...
随机推荐
- Android 用空格作为分割符切割字符串
项目中有需要用到空格作为分割符切割字符串,进而转为List. String wordStore = edWord.getText().toString(); String[] word = wordS ...
- 源码解析JDK1.8-HashMap链表成环的问题解决方案
前言 上篇文章详解介绍了HashMap在JDK1.7版本中链表成环的原因,今天介绍下JDK1.8针对HashMap线程安全问题的解决方案. jdk1.8 扩容源码解析 public class Has ...
- 归并排序-Python实现
归并排序(MergeSort) 归并排序(英语:Merge sort,或mergesort),是创建在归并操作上的一种有效的排序算法,效率为 O(n\log n)(大O符号).1945年由约翰·冯·诺 ...
- Alpha阶段项目复审(鸽牌开发小分队)
团队:鸽牌开发专业小分队 项目:必备记 集合帖:集合帖 项目复审: 团队名字 项目链接 优点 缺点和bug报告 最终名次 歪瑞古德小队 海岛漂流 1.功能齐全,上手简单2.界面简洁美观3.想法新颖,可 ...
- php实现视频拍照上传头像功能实例代码
如果要在php中实现视频拍照我们需要借助于flash插件了,由flash拍出的确照片我们再通过php的$GLOBALS ['HTTP_RAW_POST_DATA']接受数据,然后保存成图片就可以了,下 ...
- Java多线程_Future设计模式
Future模式的核心:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑. Future模式有点类似于商品订单.在网上购物时,提交订单后,在收货的这段时间里无需一直在家 ...
- 如何用VMD将轨迹文件制作动画(转载)
转载自:http://blog.sina.com.cn/s/blog_63f794950101dtte.html 很多同学想从dcd(NAMD)或者trr(gromac)文件提取一段轨迹文件做成动画. ...
- 史上!最最最简洁明了的 Java JDK 安装目录及其子目录含义 10分钟详解 - 精简归纳
Java JDK 安装目录及其子目录含义 10分钟详解 - 精简归纳 JERRY_Z. ~ 2020 / 8 / 30 转载请注明出处!️ 目录 Java JDK 安装目录及其子目录含义 10分钟详解 ...
- 【转】ANDROID LOLLIPOP SCREEN CAPTURE AND SHARING
https://datatheorem.github.io/android/2014/12/26/android-screencapture/ https://www.youtube.com/watc ...
- 认证授权:IdentityServer4
前言 上一篇文章<学习OIDC>介绍了OIDC协议,本篇开始我们就来具体来学习OIDC的具体实现IdentityServer4 学习. 一.IdentityServer4 是什么? Ide ...