zoukankan      html  css  js  c++  java
  • CAS中,如何避免比较和修改之间插入线程?

    这说的并不是ABA问题,ABA问题是比较之前某个值被改变成另一个相同的值的问题

    先来回顾原语:原子性的语句,就是一堆机器指令,CPU要么全部执行,要么全部不执行

    JAVA中的CAS:

    public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5)

    查看其native源码:

    UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h))
      UnsafeWrapper("Unsafe_CompareAndSwapObject");
      oop x = JNIHandles::resolve(x_h); // 新值
      oop e = JNIHandles::resolve(e_h); // 预期值
      oop p = JNIHandles::resolve(obj);
      HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset);// 在内存中的具体位置
      oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e, true);// 调用了另一个方法
      jboolean success  = (res == e);  // 如果返回的res等于e,则判定满足compare条件(说明res应该为内存中的当前值),但实际上会有ABA的问题
      if (success) // success为true时,说明此时已经交换成功(调用的是最底层的cmpxchg指令)
        update_barrier_set((void*)addr, x); // 每次Reference类型数据写操作时,都会产生一个Write Barrier暂时中断操作,配合垃圾收集器
      return success;
    UNSAFE_END
    

    可以看到源码中又调用了另一个原子性的方法:oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e, true);保证其原子性,避免被其它线程插入;到最后会转换成完成CAS功能的原语

    参考:

    JUC系列第三篇-CAS算法详解

  • 相关阅读:
    Windows系统下静态库和动态库的生成方法
    c语言 9-9
    c语言中统计字符串中数字字符出现的次数
    c语言 9-8
    c语言 9-7
    c语言中使用putchar显示字符串
    c语言 9-6
    c语言 9-5
    c语言 9-4
    c语言中输出字符串的长度
  • 原文地址:https://www.cnblogs.com/linyh99/p/14670521.html
Copyright © 2011-2022 走看看