原子操作实现原理

2018-08-02  本文已影响0人  kindol

一些概念

处理器如何实现原子操作

使用基于对缓存加锁或者总线加锁的方式实现多处理器之间的原子操作,但复杂的内存操作处理器依旧不能保证其原子性,如跨总线宽度、跨页表的访问。

java中实现原子操作

java通过循环CAS实现原子操作,下面讲讲使用循环CAS实现的原子操作

CAS是利用了处理器提供的CMPXCHG指令实现的。自旋CAS实现基本思路就是循环进行CAS操作直至成功为止。

java中的原子类就是利用了此

CAS

CAS 操作包含三个操作数——内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论V值是否等于A值,都将返回V的原值

CAS 有效地说明了:我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可

当多个线程尝试使用CAS同时更新一个变量,最终只有一个线程会成功,其他线程都会失败。但和使用锁不同,失败的线程不会被阻塞,而是被告之本次更新操作失败了,可以再试一次。此时,线程可以根据实际情况,继续重试或者跳过操作,大大减少因为阻塞而损失的性能。所以,CAS是一种乐观的操作,它希望每次都能成功地执行更新操作。

CAS实现原子操作的三大问题

  1. ABA问题

    CAS需要操作值的时候,会先检查旧值,如果旧值在这段时间经过了由A->B->A的变化,则无法检测出来,为解决此问题,可以引入版本号,每次改变则修改一次版本,Atomic中有提供当前引用是否等于预期引用的思路

  2. 循环时间长开销大

    自旋CAS如果长时间不成功,会带来较多CPU消耗

  3. 只能保证一个共享变量的原子操作

AtomicIntegerArray

AtomicIntegerArray会将当前的数组复制一份,所以当AtomicIntegerArray对内部的数组元素进行修改时,不会影响传入的数组

上一篇 下一篇

猜你喜欢

热点阅读