java并发机制之volatile详解

来源:互联网 发布:营销网络怎么填 编辑:程序博客网 时间:2024/05/16 09:25

java并发机制之volatile详解

在java的多线程编程中synchronized和volatile使用十分广泛。volatile是一个轻量级的synchronized。它在多核并发编程中可以保证共享变量的“可见性“,在一个线程修改了被volatile修饰的共享变量时可以保证另外一个线程可以读到这个修改后的的值,避免多个变量独到的值内容不同。合适使用volatile 修饰符可以有效避免共享变量多线程中表现值不一致的问题。

volatile是在java语言规范第三版中推出的。java允许线程访问共享变量,为了确保共享变量被准确和一致的更新,线程应确保排它锁的访问共享变量。使用volatile修饰的变量在被多个线程访问时可以起到排它效果。

volatile实现原理

要想了解volatile的实现原理前我们需要对cpu的相关术语有所了解。

术语 英文单词 描述 内存屏障 memory barriers 一组处理器指令,用于限制对内存操作的顺序 缓冲行 cache line cpu高速缓存中可以分配的最小单位。处理器在填写缓存行时会加在整个缓存行 原子操作 atomic operations 不可中断的一个或一系列操作 缓存行填充 cache line fill 当处理器识别到内存中可读数值可以缓存时,将整个缓存行加在道cpu的高速缓存中 缓存命中 cache hit 如果进行高速缓存填充操作的内存位置仍然是下次操作的内存位置就直接冲高速缓存中或缺 写命中 write hit 当处理器将操作数写回到内存缓存时,它首先检测操作数的内存地址是否在缓存中。如果内存地址在某缓存行中,则将操作数更新到缓存行中 写缺失 write misses the cache 一个有效的缓存行被写入到一个无效的内存中

要想了解volatile的实现原理我们可以从被valatile修饰的变量转化为汇编语言后的样子分析(汇编不够精通在此不谈)。被volatile修饰的变量的汇编语句中会发现Lock 前缀的命令。

被Lock前缀修饰的命令在多核处理器中引发两种事情:
_ 会将当前处理器的缓存行信息写会内存。
_写回内存操作会将其它处理器的相应的缓存行无效

被volatile修饰的变量在执行写操作时会发出一个Lock命令。为了保证在多线程模式下数据的可见性,就必须实现“缓存一致性协议“。实现缓存一致性协议的线程通过不断嗅探总线上传递的数据来检测自己缓存信息的有效性。当发现自己的缓存行地址被修改就将当前处理器的缓存行设置为无效标志。当需要对内存数据进行写操作时再将数据加入到自己的缓存中进行处理。

volatile中通过lock命令前缀和缓存一致性协议来保证起多核多线程状态下的可见性。

0 0