• 【Java并发编程】2、无锁编程:lock-free原理;CAS;ABA问题


    转自:http://blog.csdn.net/kangroger/article/details/47867269

    定义

    无锁编程是指在不使用锁的情况下,在多线程环境下实现多变量的同步。即在没有线程阻塞的情况下实现同步。这样可以避免竞态、死锁等问题。

    原理

    CAS是指Compare-and-swap或Compare-and-Set 
    CAS是一个原子操作,用于多线程环境下的同步。它比较内存中的内容和给定的值,只有当两者相同时(说明其未被修改),才会修改内存中的内容。 
    实现如下:

    int compare_and_swap(int* reg, int oldval, int newval)
    {
      ATOMIC();
      int old_reg_val = *reg;
      if (old_reg_val == oldval)
         *reg = newval;
      END_ATOMIC();
      return old_reg_val;
    }

    bool compare_and_swap(int *accum, int *dest, int newval)
    {
      if (*accum == *dest) {
          *dest = newval;
          return true;
      } else {
          *accum = *dest;
          return false;
      }
    }

    返回bool值得好处是可以知道是否设置成功。

    在实际环境中,使用的是:

    bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...)
    type __sync_val_compare_and_swap (type *ptr, type oldval, type newval, ...)

    在使用CAS时,需要先获取操作变量的值并放到oldval中,之后调用cas函数,直到调用成功。例如给变量val赋值

    while(true)
    {
        int oldval=val;
        if(__sync_bool_compare_and_swap(&val, oldval, newval))
            break;
    }

    ABA问题

    在多线程环境中,使用lock-free的CAS时,如果一个线程对变量修改2次,第2次修改后的值和第1次修改前的值相同,那么可能就会出现ABA问题。以上面的例子为例: 
    假设有两个线程P1和P2,P1执行完int oldval=val后被其他线程抢占。P2线程在此期间修改了val的值(可能多次修改),但最终val的值和修改前一样。当P1线程之后运行CAS函数时,并不能发现这个问题。这就是ABA问题。

    解决方法

    一个常用的方法是添加额外的“tag”或“stamp”位来标记是指针是否被修改过。

    参考: 
    Compare-and-swap

    ABA problem

  • 相关阅读:
    Java入门第37课——猜字母游戏之设计数据结构
    Sublime Text 3 常用快捷键
    WEB前端响应式布局之BootStarp使用
    js让页面逐渐变透明,直到消失
    Vue实战之插件 sweetalert 的使用
    搭建jQuery开发环境
    Layui数据表单的编辑
    SpringBoot基于websocket的网页聊天
    layui修改数据的时候下拉框和选择框默认选中
    Linux 软件编译、安装、删除
  • 原文地址:https://www.cnblogs.com/wangzhongqiu/p/6464172.html
Copyright © 2020-2023  润新知