zoukankan      html  css  js  c++  java
  • ConcurrentLinkedQueue基于JDK1.8源码学习心得

    最近在读《Java并发编程的艺术》,书中关于ConcurrentLinkedQueue的描述并不是基于JDK1.8

    相较于JDK1.8版本的,还是修改了挺多地方的,比如关于HOPS的设计意图直接去掉了

    参考贴:https://www.jianshu.com/p/08e8b0c424c0
    https://blog.csdn.net/lejustdoit/article/details/98477819?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase

    大部分东西上面两篇博客已经讲的很清楚了,这里补充一点自己的学习时候没清楚的点

     1 public boolean offer(E e) {
     2     checkNotNull(e);
     3     final Node<E> newNode = new Node<E>(e);
     4     
     5     for (Node<E> t = tail, p = t;;) {
     6          Node<E> q = p.next;
     7          if (q == null) {
     8              if (p.casNext(null, newNode)) {
     9                  if (p != t)
    10                      casTail(t, newNode);
    11                  return true;
    12              }//1CAS自旋失败
    13          }
    14          else if (p == q)//2某个线程提前出队节点导致p=q,详情见第一篇参考贴
    15              p = (t != (t = tail)) ? t : head;
    16          else//3让p指针始终指向尾节点
    17              p = (p != t && t != (t = tail)) ? t : q;
    18     }
    19 }

    1、注解1,2,3都是当前节点插入失效,需要重新插入,2考虑了tail滞后于head的情况(节点出队,详情见第一篇参考贴)

    注解3和4中的t=tail这步操作很神奇,它有效的减少了CAS更新tail节点的次数,这也是曾经的HOPS的设计意图

    t=tail跟CAS相比有线程安全问题,但是这里对线程安全的要求并不高,因为判断是否真的是尾节点在if (q == null),所以它只是象征性的更新一下尾节点

    若刚好更新成为尾节点,那么CAS更新casTail(t, newNode)这步不就不用做了

    若运气不好没有更新尾节点,那么并不影响下次循环

    2、p = (t != (t = tail)) ? t : head;

    这里比较的是地址是否相同,而不是值

    刚开始以为一直是true,先执行t=tail,然后判断t!=t,debug的时候发现不是

    首先判断t的地址是否是tail,然后才是t=taill,测试代码如下

     1 class No {
     2     int k, v;
     3     public No(int k, int v) {
     4         this.k = k;
     5         this.v = v;
     6     }
     7 }
     8 No B = new No(3, 4);
     9 No A = B;//当A=B时返回1 2
    10 //No A = new No(1, 9);//当A!=B时返回3 4
    11 No C = new No(1, 2);
    12 No D = (A!=(A=B))?A:C;
    13 System.out.println(D.k + " " + D.v);

    然后还有一句这个,p = (p != t && t != (t = tail)) ? t : q;

    根据&&的特性,如果p=t那么&&后的语句将不会被执行,也就是说t最后没有被赋值

    3、可以发现程序当前已经经过casNext方法,可以发现此时p指针并没有指向新节点newNode

  • 相关阅读:
    PB中的Grid视图
    MVC加jquery的无刷新列表分页摘要
    Quartz.Net 1.30的一些设置说明
    将Excel的数据库字典导到PDM中
    HubbleDotNet使用备忘
    EntLib5.0 日志应用程序块(logging) 使用与配置
    生成随机密码
    网站整合QQ登录
    PB代码参考段
    SQL查询之 Pivot 详解
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/13192068.html
Copyright © 2011-2022 走看看