原子操作的实现原理

原子操作的实现原理

九月 13, 2018 本文总阅读量

原子(atomic),本意是指“不能被进一步分割的粒子”。原子操作意味着“不可被中断的一个或一系列操作”。
接下去一起看看在Intel处理器和Java里是如何实现原子操作的。

术语定义

Cache line(缓存行)
Compare and Swap(比较并交换)
cpu pipeline(cpu流水线)
memory order violation(内存顺利冲突)
处理器实现原子操作

当处理器读取内存的一个字节时,其它处理器不能访问这个字节的内存地址,最新的处理器能自动保证处理器对同一缓存行里进行16/32/64位的操作是原子的。处理器提供总线锁定和缓存锁定的机制保证复杂内存操作的原子性。

1、总线锁保证原子性

使用处理器提供的一个LOCK#信号,当一个处理器在总线上输出此信号时,其它处理器的请求将被阻塞,那么该处理器就能独自共享内存。

2、缓存锁保证原子性

“缓存锁定”指内存区域如果被缓存在处理器的缓存行中,并且在Lock操作期间被锁定,那么当它执行锁操作回写到内存时,处理器不需要在总线上声言LOCK#信号,而是修改内部的内存地址,通过缓存一致性机制保证操作的原子性。
例外:当操作的数据不能被缓存在处理器内部,或操作的数据跨多个缓存行,处理器会调用总线锁定。

缓存一致性

缓存一致性会阻止同时修改由两个以上处理器的内存区域数据,当其他处理器回写被锁定的缓存行数据时,会使其它处理器的缓存行无效。

Java原子操作实现

在Java中通过锁和循环CAS的方式实现原子操作。

CAS

jvm中的CAS操作是基于处理器的CMPXCHG指令实现的,CAS存在三个问题:

ABA问题
循环时间长开销大
只能保证一个共享变量的原子操作

锁机制保证了只有获得锁的线程才能操作锁定的内存区域,具体实现可以参考java synchronized