java线程之volatile关键字
2018-03-25 本文已影响0人
dimdark
参考书籍: <<java并发编程的艺术>>
这篇文章是自己阅读该书籍时的读书笔记
volatile
的定义
volatile
是轻量级的 synchronized
, 它在多处理器开发中保证了共享变量的可见性; volatile
比 synchronized
的使用和执行成本更低, 因为它不会引起线程上下文的切换和调度;
可见性: 当一个线程修改一个共享变量时, 另外一个线程(在修改之后)能读到这个修改的值;
volatile
的实现原理
- 与实现原理相关的CPU术语
术 语 | 描述 |
---|---|
memory barriers(内存屏障) | 是一组处理器指令, 用于实现对内存操作的顺序限制 |
cache line(缓冲行) | 缓存中可以分配的最小存储单位, 处理器填写缓存线时会加载整个缓存线, 需要使用多个主内存读周期 |
atomic operations(原子操作) | 不可中断的一个或一系列操作 |
cache line fill(缓存行填充) | 当处理器识别到从内存中读取操作数是可缓存的, 处理器读取整个缓存行到适当的缓存(L1, L2, L3 或 所有) |
cache hit(缓存命中) | 如果进行高速缓存行填充操作的内存位置仍然是下次处理器访问的地址时,处理器从缓存中读取操作数, 而不是从内存读取 |
write hit(写命中) | 当处理器将操作数写回到一个内存缓存的区域时, 它首先会检查这个缓存的内存地址是否在缓存行中, 如果存在一个有效地缓存行, 则处理器将这个操作数写会到缓存, 而不是写回到内存, 这个操作被称为写命中 |
write misses the cache(写缺失) | 一个有效地缓存行被写入到不存在的内存区域 |
-
volatile
关键字的实现原理
被volatile修饰的共享变量进行写操作时会在编译后的汇编代码增加一个lock前缀的指令, 这条lock前缀的指令的作用:- 将当前处理器缓存行的数据写回到系统内存
- 这个写回内存的操作会使其他CPU里缓存了该内存地址的数据无效
这里重点关注 缓存一致性协议(机制):
每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是否过期, 当处理器发现自己缓存行对应的内存地址(的值)被修改, 就会将当前处理器的缓存行设置成无效状态, 当处理器对这个数据进行修改操作的时候, 会重新从系统内存中把数据读到处理器缓存里