MyException - 我的异常网
当前位置:我的异常网» 移动开发 » Java多线程高并发进阶篇(1)-volatile实现原理剖析

Java多线程高并发进阶篇(1)-volatile实现原理剖析

www.MyException.Cn  网友分享于:2018-04-16  浏览:0次
Java多线程高并发进阶篇(一)-volatile实现原理剖析

我们知道,在JVM的类加载机制中,是将外围的源码文件编译成字节码文件(.class)后加载到JVM中,然后Java通过执行引擎执行字节码,最终转化为汇编指令由CPU执行.我们说的并发编程机制,当然离不开JVM的实现和CPU的指令集.

了解JMM(Java Memory Model,Java内存模型)都知道,JMM是围绕着原子性,有序性,可见性展开的.后面我会专门写一篇,阐述Java内存模型以及它与处理器内存模型,以及顺序一致性内存模型的关系.

1.volatile的定义

在Java语言规范中,对volatile的定义如下:

Java编程语言允许线程访问共享变量,为了确保共享变量能准确的访问一致性的更新,线程应该确保通过排它锁单独获得这个变量,因此Java语言提供了volatile.如果一个变量被定义为volatile,那么Java线程的内存模型(也叫线程的本地内存)看到这个变量的内容是一致的.换句话说,Java语言提供volatile,是为了保证线程之间共享变量的可见性.

 

2.volatile的实现原理

在了解volatile之前,我们需要明白CPU中的一些专业术语.


 

在了解了上面的专业术语后,我们就了解下volatile如何保证可见性.

有volatile修饰的共享变量在进行写操作时,转变成汇编指令时,会多出一行lock addl $0×0,(%esp);

 

lock前缀指令在多核处理器下会引发两件事情:

①将当前处理器缓存行的数据全部写回到系统内存(JMM中的主内存).

②在这个写回主内存的操作会使在其他处理器(CPU)中缓存了该内存地址的数据无效.

这里我们解释一下.

为了提高处理速度,处理器不直接和主内存进行通信,而是先将主内存的数据读取到处理器的内部缓存中(一级或二级缓存或其他).如果对声明了volatile的变量进行写操作,JVM就会向处理器发送一条lock前缀的指令,如红色字体部分,然后将这个变量所在的缓存行数据写回到主内存.如果其他处理器缓存的该共享变量的值还是旧的,那么后续的操作就会有问题.因此,在多处理器情况下,为了保证各个处理器缓存该共享变量的内容一致,就需要根据缓存一致性协议,每个处理器通过嗅探总线上传播的数据来检查自己的缓存行是否过期了,如果发现过期了,就会把自身存储该共享变量的缓存行置为无效状态,当处理器需要对这个数据进行修改操作时,那么就需要去主内存重新读取这个共享变量的值,此时当然读取到的是上一个处理器修改过的内容了.

 

3.关于volatile实现原理两条原则的详述

在2中,我们说到了lock指令在多处理器情况下引发的两件事情.我们来具体介绍下这两件事情.

①lock指令会引起理器存回写到内存

旧型号的处理器中,Lock前缀指令执行期间,会声言一个LOCK#信号,该信号确保处理器在指令执行期间,可以独占共享内存(也就是主内存).当一个处理器在总线上声言LOCK#信号时,其他处理器的请求将会被阻塞.这种方式叫"总线锁"

但是在最新型号的处理器中,不再使用LOCK#信号锁总线,而是锁缓,因为锁总线的开销太大了.如果处理器访问的内容已经缓存在处理器内部,它会锁定该内容所在的内存区域的缓存行,并将该缓存行内容写回到共享内存(也就是主内存),并使用缓存一致性协议保证修改的原子性,这个过程叫做"缓存锁定".

这里要说明一点:存一致性机制会阻止同修改由两个以上理器存的内存区域数据。

一个理器的存回写到主内存会致其他理器的存无效

在处理器中,使用MESI(修改,独占,共享,无效)控制协议 ,去维护处理器内部的缓存和其他处理器的缓存一致性.在多核处理器系统中,处理器能嗅探到其他处理器访问主内存以及它们的内部缓存.处理器使用嗅探技术保证它的内部缓存,主内存,其他处理器的缓存的数据跟总线上保持一致.

比如,PentiumP6 family理器中,如果一个器通过嗅探检测到其他理器打算将共享变量回写到主内存地址,那么个地址对于缓存了该数据缓存行的处理器来说于共享状态,这个处理器就会把自身处理器缓存中对应的缓存数据行置为无效状态.

 

来一张图,让蒙圈的小伙伴们醒醒.JMM的内存结构示意图.



 

文章评论

当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
为什么程序员都是夜猫子
为什么程序员都是夜猫子
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
旅行,写作,编程
旅行,写作,编程
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
代码女神横空出世
代码女神横空出世
如何成为一名黑客
如何成为一名黑客
每天工作4小时的程序员
每天工作4小时的程序员
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
那些争议最大的编程观点
那些争议最大的编程观点
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
中美印日四国程序员比较
中美印日四国程序员比较
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
 程序员的样子
程序员的样子
我是如何打败拖延症的
我是如何打败拖延症的
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
程序员都该阅读的书
程序员都该阅读的书
鲜为人知的编程真相
鲜为人知的编程真相
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
编程语言是女人
编程语言是女人
程序员的鄙视链
程序员的鄙视链
总结2014中国互联网十大段子
总结2014中国互联网十大段子
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
一个程序员的时间管理
一个程序员的时间管理
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
程序员和编码员之间的区别
程序员和编码员之间的区别
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
我的丈夫是个程序员
我的丈夫是个程序员
程序员应该关注的一些事儿
程序员应该关注的一些事儿
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
程序员必看的十大电影
程序员必看的十大电影
Java程序员必看电影
Java程序员必看电影
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
老程序员的下场
老程序员的下场
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有