zl程序教程

您现在的位置是:首页 >  大数据

当前栏目

【并发编程042】CAS操作的原理?

并发编程原理 操作 CAS
2023-09-27 14:29:27 时间

CAS操作的原理?

CAS: Compare and Swap, 即比较再交换。

jdk5 增加了并发包 java.util.concurrent.*, 其下面的类使用 CAS 算法实现了区别于 synchronized 悲 观锁的一种乐观锁 。JDK 5 之前 Java 语言是靠 synchronized 关键字保证同步的, 这是一种独占锁, 也是是悲观锁。

所谓的 CAS, 其实是个简称, 全称是 Compare And Swap, 对比之后交换数据 。 上面的方法, 有几 个重要的参数:

(1) this, Unsafe 对象本身, 需要通过这个类来获取 value 的内存偏移地址。

(2) valueOffset, value 变量的内存偏移地址。

(3) expect, 期望更新的值。

(4) update, 要更新的最新值。

其中步骤 (1) 和步骤 (2) 是根据内存偏移地址获取当前的值value, expect值是未修改之前的value 值 。 如果修改时通过内存偏移地址获取到的value与except的value值一样, 则进行更新, 否则不更新, 再次从新获取value值, 循环下去, 直到成功为止 。 (通过源码阅读)

image-20220415120042495

这里看到有一个 LOCK_IF_MP, 作用是如果是多处理器, 在指令前加上 LOCK 前缀, 因为在单 处理器中, 是不会存在缓存不一致的问题的, 所有线程都在一个 CPU 上跑, 使用同一个缓存区, 也就不存在本地内存与主内存不一致的问题, 不会造成可见性问题 。 然而在多核处理器中, 共 享内存需要从写缓存中刷新到主内存中去, 并遵循缓存一致性协议通知其他处理器更新缓存 。 Lock 在这里的作用:

• 在 cmpxchg 执行期间, 锁住内存地址 [edx], 其他处理器不能访问该内存, 保证原子性 。 即 使是在 32 位机器上修改 64 位的内存也可以保证原子性。

• 将本处理器上写缓存全部强制写回主存中去, 保证每个线程的本地内存与主存一致。

• 禁止 cmpxchg 与前后任何指令重排序, 防止指令重排序。