聊聊并发(1):深入分析volatile的实现原理-java开发java经验技巧

聊聊并发(1):深入分析volatile的实现原理-java开发java经验技巧

ID:30853801

大小:54.00 KB

页数:6页

时间:2019-01-04

聊聊并发(1):深入分析volatile的实现原理-java开发java经验技巧_第1页
聊聊并发(1):深入分析volatile的实现原理-java开发java经验技巧_第2页
聊聊并发(1):深入分析volatile的实现原理-java开发java经验技巧_第3页
聊聊并发(1):深入分析volatile的实现原理-java开发java经验技巧_第4页
聊聊并发(1):深入分析volatile的实现原理-java开发java经验技巧_第5页
资源描述:

《聊聊并发(1):深入分析volatile的实现原理-java开发java经验技巧》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库

1、聊聊并发(1):深入分析Volatile的实现原理-编程开发技术聊聊并发(1):深入分析Volatile的实现原理原文出处:方腾E引言在多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。它在某些情况下比synchronized的开销更小,本文将深入分析在硬件层面上Inter处理器是如何实现Volatile的,通过深入分析能帮助我们止确的使用Volatile变量。术语定义术语英文单

2、词描述共享变量在多个线程z间能够被共享的变量被称为共享变量。共享变虽包括所冇的实例变屋,静态变量和数组元素。他们都被存放在堆内存中,Volatile只作用于共享变量。内存屏障MemoryBarriers是一组处理器指令,用于实现対内存操作的顺序限制。缓冲行Cacheline缓存中可以分配的最小存储单位。处理器填写缓存线时会加载整个缓存线,需耍使用多个主内存读周期。原子操作Atomicoperations不可中断的一个或一系列操作。缓存行填充cachelinefill当处理器识別到从内存中读取操作数是对缓存的,处理器读取整个缓存行到适当的缓存(L1,L2,L3的或所有)缓存命中c

3、achehit如果进行高速缓存行填充操作的内存位置仍然是下次处理器访问的地址时,处理器从缓存中读取操作数,而不是从内存。写命中writehit当处理辭将操作数写回到一个内存缓存的区域吋,它首先会检查这个缓存的内存地址是否在缓存行屮,如果存在一个何效的缓存行,则处理器将这个操作数写制到缓存,而不是写制到内存,这个操作被称为写命中。写缺失writemissesthecache一个有效的缓存行被写入到不存在的内存区域。Volat订e的官方定义Java语言规范第三版中对volatile的定义如下:java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致的更新,线程应该确保通

4、过排他锁单独获得这个变量。Java语言提供了volatile,在某些情况下比锁更加方便。如果一个字段被声明成volatile,java线程内存模型确保所有线程看到这个变量的值是一致的。为什么要使用VolatileVolatile变量修饰符如果使用恰当的话,它比synchronized的使用和执行成本会更低,因为它不会引起线程上下文的切换和调度。Volatile的实现原理那么Volatile是如何来保证可见性的呢?在x86处理器下通过工具获取J1T编译器生成的汇编指令來看看对Volatile进行写操作CPU会做什么事情。Java代码:instance=newSingleton()

5、;//instance是volatile变量汇编代码:0x01a3dcld:0,(%esp);movb$0X0,0X1104800(%csi);0x01a3dc24:?lock?addl$0X有volatile变量修饰的共享变量进行写操作的吋候会多第二行汇编代码,通过查IA-32架构软件开发者手册可知,lock前缀的指令在多核处理器下会引发了两件事情。•将当前处理器缓存行的数据会写回到系统内存。•这个写冋内存的操作会引起在其他CPU里缓存了该内存地址的数据无效。处理器为了提高处理速度,不直接和内存进行通讯,而是先将系统内存的数据读到内部缓存(L1,L2或其他)后再进行操作,但操

6、作完之后不知道何时会写到内存,如果对声明了Volatile变量进行写操作,JVM就会向处理器发送一条Lock前缀的指令,将这个变量所在缓存行的数据写回到系统内存。但是就算写回到内存,如果其他处理器缓存的值还是旧的,再执行计算操作就会有问题,所以在多处理器下,为了保证各个处理器的缓存是一致的,就会实现缓存一致性协议,每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自C缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,当处理器要对这个数据进行修改操作的时候,会强制重新从系统内存里把数据读到处理器缓存里。这两件事情在TA-32软件开发

7、者架构手册的第三册的多处理器管理章节(第八章)中有详细阐述。Lock前缀指令会引起处理器缓存回写到内存。Lock而缀指令导致在执行指令期间,声言处理器的LOCK#信号。在多处理器环境屮,LOCK#信号确保在声言该信号期间,处理器可以独占使用任何共享内存。(因为它会锁住总线,导致其他CPU不能访问总线,不能访问总线就意味着不能访问系统内存),但是在最近的处理器里,LOCK#信号一•般不锁总线,而是锁缓存,毕竟锁总线开销比较人。在&1.4章节有详细说明锁定操作对处理器缓存的影响,对丁Intel4

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。