Skip to content

Latest commit

 

History

History
23 lines (22 loc) · 2.32 KB

Atomic.md

File metadata and controls

23 lines (22 loc) · 2.32 KB

简述原子操作的原理

一. 处理器如何实现原子操作

处理器使用基于对缓存加锁总线加锁的方式来实现多处理器之间的原子操作。

1.1 处理器自动保证基本内存操作的原子性

  • 首先处理器会自动保证基本的内存操作的原子性。
  • 当一个处理器读取一个字节时,其他处理器不能访问这个字节的内存地址。

1.2 使用总线锁保证原子性

  • 总线锁就是使用处理器提供的一个LOCK#信号,当一个处理器在总线上输出此信号时,其他处理器的请求将被阻塞住,那么该处理器可以独占使用共享内存。

1.3 使用缓存锁保证原子性

  • 因为总线锁定的开销比较大,最近的处理器在某些场合下使用缓存锁定代替总线锁定来进行优化
  • “缓存锁定”就是处理器不在总线上声言LOCK#信号,而是修改内部的内存地址,并允许它的缓存一致性机制来保证操作的原子性,因为缓存一致性机制会阻止同时修改被两个以上处理器缓存的内存区域数据,当其他处理器回写已被锁定的缓存行的数据时会起缓存行无效。
  • 有两种情况下处理器不会使用缓存锁定。
    • 第一种情况是:当操作的数据不能被缓存在处理器内部,或操作的数据跨多个缓存行(cache line),则处理器会调用总线锁定。
    • 第二种情况是:有些处理器不支持缓存锁定。对于Inter486和奔腾处理器,就算锁定的内存区域在处理器的缓存行中也会调用总线锁定。

二. JAVA如何实现原子操作

在java中可以通过锁和循环CAS的方式来实现原子操作。

2.1 使用循环CAS实现原子操作

  • 自旋CAS实现的基本思路就是循环进行CAS操作直到成功为止.
  • 从Java1.5开始JDK的并发包里提供了一些类来支持原子操作,如AtomicBoolean(用原子方式更新的 boolean 值),AtomicInteger(用原子方式更新的 int 值),AtomicLong(用原子方式更新的 long 值).
  • CAS虽然很高效的解决原子操作,但是CAS仍然存在三大问题。ABA问题,循环时间长开销大和只能保证一个共享变量的原子操作。

2.2 使用锁机制实现原子操作

锁机制保证了只有获得锁的线程能够操作锁定的内存区域。