CAS利用的底层原理(总线锁定机制和缓存锁定机制 )

[复制链接]
发表于 2025-11-11 19:32:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
目次
处置惩罚器级别的实现
总线锁定机制
缓存锁定机制 
MSEI表现缓存行的四种状态
MESI协议状态转换

CAS利用是不包管可见性的
CAS根本概念
ABA标题的处置惩罚
性能思量 


先总结一下,CAS(Compare And Swap)是一种原子利用,它比力当前内存值与渴望值,如果相当则更新为新值,CAS是一种硬件级的原子利用,通过总线锁或缓存锁实现原子性,在使用缓存锁的时间缓存同等性协议包管数据同等性。
而Java通过native方法调用底层CAS指令,须要思量ABA标题和性能优化,而cas这种机制包管了在多处置惩罚器体系中的原子利用,是实现无锁并发的底子。
处置惩罚器级别的实现

   x86汇编中的CMPXCHG指令示例
lock cmpxchg [内存地点], 新值
  处置惩罚器通过特别的指令(如x86的CMPXCHG)来实现CAS利用,并使用LOCK前缀包管利用的原子性。 

总线锁定机制

   CPU1 ----┐
CPU2 ----├── 总线 -----> 内存
CPU3 ----┘
         ↑
      LOCK信号 
  当一个CPU发出LOCK信号时,其他CPU无法通过总线访问内存,包管了利用的原子性。但这种方式开销较大。

缓存锁定机制 

   CPU1 Cache [数据A: M] ─┐
CPU2 Cache [数据A: I]   ─┼── 总线 ──> 内存[数据A]
CPU3 Cache [数据A: I]   ─┘
  使用缓存同等性协议(MESI),通过缓存状态控制来包管原子性,服从更高。
MSEI表现缓存行的四种状态

M(Modify)表现共享数据只缓存在当前 CPU 缓存中, 而且是被修改状态,也就是缓存的数据和主内存中的数据差异等
E(Exclusive)表现缓存的独占状态,数据只缓存在当前 CPU 缓存中,而且没有被修改
S(Shared)表现数据大概被多个 CPU 缓存,而且各个缓存中的数据和主内存数据同等
I(Invalid)表现缓存已经失效
MESI协议状态转换

CPU1实行CAS:
1. 发出监听哀求
2. 等候其他CPU相应
3. 确认无辩论后实行
4. 广播状态变动
CPU在读取一个数据时会先发起监听,去监听其他CPU的对这个数据缓存行的状态。
如果本CPU缓存行状态是I,则须要从内存中读取,并把缓存行状态置为S。
如果本CPU缓存行的状态不是I,则可以直接读取缓存中的值,如果其他CPU也有该数据的缓存且状态是M,则须要等候其把缓存更新到内存后再读取。
CPU更新了缓存行的状态了之后会发广播来更新其他CPU的缓存行状态。


CAS利用是不包管可见性的

这一点要特别留意,CAS的利用是不包管可见性的,可见性是实现CAS利用的条件,如果连可见性都包管不了,这又怎么实现CAS利用?
CAS利用通常与volatile共同使用,通过内存屏蔽包管可见性。

CAS根本概念

  1. // CAS操作的伪代码
  2. public boolean compareAndSet(int expectedValue, int newValue) {
  3.     // 原子操作,比较并交换
  4.     // V是要更新的变量,E是期望值,N是新值
  5.     if (V == expectedValue) {
  6.         V = newValue;
  7.         return true;
  8.     }
  9.     return false;
  10. }
复制代码
 CAS(Compare And Swap)是一种原子利用,它比力当前内存值与渴望值,如果相当则更新为新值。

ABA标题的处置惩罚

 
  1. public class AtomicStampedReference<V> {
  2.     private static class Pair<T> {
  3.         final T reference;
  4.         final int stamp;
  5.         
  6.         private Pair(T reference, int stamp) {
  7.             this.reference = reference;
  8.             this.stamp = stamp;
  9.         }
  10.     }
  11. }
复制代码
ABA是CAS利用的经典标题了,可以通过版本号或时间戳办理ABA标题。
性能思量 

  1. // 自旋等待示例
  2. public void spinLock() {
  3.     while (!cas.compareAndSet(false, true)) {
  4.         // 自旋等待
  5.         Thread.onSpinWait(); // Java 9+
  6.     }
  7. }
复制代码
CAS失败时通常接纳自旋等候,须要思量自旋次数和退避战略。 
 
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表