zoukankan      html  css  js  c++  java
  • 链表的无锁操作 (JAVA)

    看了下网上关于链表的无锁操作,写的不清楚,遂自己整理一部分,主要使用concurrent并发包的CAS操作。

    1. 链表尾部插入

    待插入的节点为:cur

    尾节点:pred

    基本插入方法:

    do{

      pred = find_tail();              //重新找尾节点

    }(! pred.next.compareAndSet(NULL, cur))  //pred.next 是否为NULL,是则将其指向cur,不是则有新的节点插入

    这种插入方法是不带标记的,如果不涉及链表删除这个方法是可行的。

    但是如果有删除操作,pred节点可能会被删除,所以我们需要再加入一个标记位判断pred是否被删除(false 未删除)

    do{

      pred = find_tail();              

    }(! pred.next.compareAndSet(NULL, cur, false, false));  //检查pred.next是被否标记为false,并标记为false

    因为我们插入是对pred.next进行CAS操作,所以虽然要判断pred是否被删除,我们却只能看它的next域的标记,所以在删除的时候要和这里配合置next位为true让本次添加不成功

    注意这里的next的置位与否不是next节点的,是pred本身的,因为只能从pred自己看到是否被删除,所以节点的数据结构不包含flag,节点的next域包含flag,这种结构具体参考AtomicMarkableReference

    这里如果先判断pred是否为false是不行的,所有操作必须在CAS中完成,因为判断的一瞬间是OK的但是不代表执行CAS的时候也是OK的

    (TIP:因为是队尾,next域是NULL,但是仍然含有标记位,每个新node尾节点添加的时候都是node.next = new AtomicMarkableReference<Node>(null,false))

    2. 链表删除节点

    待删除的节点为:cur

    do{

      succ = cur.next;        //重新找next节点

      if (cur.next == true) break;   //有线程已经将其逻辑删除

      pred = pred(cur);       //找pred节点

      flag1 = cur.next.compareAndSet(succ, succ, false, true);  //第一个CAS将cur.next置为true,防止添加操作和重复删除操作

      if (! flag1) continue;

      flag2 = pred.next.compareAndSet(cur, succ, false, false);  //第二个CAS将pred.next指向succ,并将succ的为置为false

      if(! flag2) continue;

    }(0);

    这里两次CAS操作,第一次置位,也就是所谓的逻辑删除,和添加节点相呼应,这里标记完了之后在第二个CAS执行前,往本节点之后的添加都不成功

    本次CAS失败说明有其它线程的删除操作或CAS之前有往cur的next有添加操作(succ改变),返回再次尝试

    第二次则将原来指向cur的pred.next指向succ,进行物理删除,这里succ已经不能改变了,因为第一次CAS成功之后next置位其他线程既不能添加也不能删除

    但是pred可以被删除,pred被删除之后导致pred.next置位,这次CAS失败。

    这里第二次CAS操作可能其他地方也有相同的代码,如果本线程在第一次CAS调用完后阻塞,可以让其他线程看到这个标记后帮忙进行节点删除和清置位,这也是wait free的设计的核心思想

    3. 链表某节点插入

    实现原理相同,不多赘述,一定要注意和删除的判断过程是保证自洽的。

  • 相关阅读:
    适合于小团队产品迭代的APP测试流程
    【转】软件测试上线标准
    安全性测试之修改密码
    LoadRunner 实现监控Tomcat
    【转】人生应该接受的教育
    晓光聊《小厂如何做测试》
    由测试需要多少编程知识想到的
    12款很棒的浏览器兼容性测试工具推荐
    最近感悟测试人员需要的一种能力
    APP测试功能点总结
  • 原文地址:https://www.cnblogs.com/jkserge/p/8955783.html
Copyright © 2011-2022 走看看