原子操作(atomic operation)意 为“不可被中断的一个或一系列操作
处理器如何实现原子操作
总线锁定
使用处理器提供的一个 LOCK#信号,当一个处理器在总线上输出此信号时,其他处理器的请求将被阻塞住,那么该 处理器可以独占共享内存
总线锁定把CPU和内存之间的通信锁住了,这使得锁定期间,其他处 理器不能操作其他内存地址的数据,所以总线锁定的开销比较大
缓存锁定
同一时刻,我们通常仅需要保证对某个内存地址的操作是原子性即可,由于总线锁定开销大,某些场合下,处理器会使用缓存锁定替代总线锁定
缓存锁定是指内存区域如果被缓存在处理器的缓存行中,并且在Lock操作期间被锁定,那么当它执行锁操作回写到内存时,处理器不在总线上声明LOCK#信号,而是修改内部的内存地址,并允许它的缓存一致性机制来保证操作的原子性
缓存一致性机制会阻止同时修改由两个以上处理器缓存的内存区域数据,当其他处 理器回写已被锁定的缓存行的数据时,会使缓存行无效
两种不会使用缓存锁定的情况
- 当操作的数据不能被缓存在处理器内部,或操作的数据跨多个缓存行
(cache line)时,则处理器会调用总线锁定 - 有些处理器不支持缓存锁定
Java如何实现原子操作
Java中可以通过锁和循环CAS的方式来实现原子操作
循环CAS实现原子操作
JVM中的CAS操作正是利用了处理器提供的CMPXCHG指令实现的.
CAS原子操作的三大问题
- ABA问题 可以尝试在更新对象中添加预期引用的方式解决
- 循环时间长,开销大
- 只能保证一个共享变量的原子操作 可以把多个共享变量放在一个对象中进行CAS操作(AtomicReference)
使用锁机制实现原子操作
锁机制保证了只有获得锁的线程才能够操作锁定的内存区域。JVM内部实现了很多种锁 机制,有偏向锁、轻量级锁和互斥锁
文章链接 https://fangzongzhou.github.io/2020/10/14/计算机/技术栈/Java/并发编程/原子操作/