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算法详解

  • 相关阅读:
    FTP命令行工具NCFTP
    XP 通过无线网卡 建立对等网
    Silverlight WCF 压缩
    EntityFramework Linq查询
    UCS2编码转换C#
    C#7Z压缩
    c#公钥加密私钥解密和验证
    SVN global ignore pattern for c#
    典型的DIV CSS三行二列居中高度自适应布局
    VC#窗体的大小设置
  • 原文地址:https://www.cnblogs.com/linyh99/p/14670521.html
Copyright © 2011-2022 走看看