为什么会出现p == q
  假设下面这种情况:

  在第一种情况下,线程A执行offer操作:
  1、第一次循环的时候
  2、tail = node0, p = t = node0
  3、执行 Node<E> q = p.next; 之后q = p.next,也是node0.next
  4、执行 if (q == null),不满足,继续往下
  到了 else if (p == q) 这一步的时候线程A暂停
  线程A现在的结果是:
  head = node0
  tail = node0
  t = node0
  p = node0
  q = node0.next
  因为程序时多线程的,我们假设线程A暂定在了第4步,接下来看线程B,线程B执行poll操作:
  第一次循环:
  · head = node0, p = h = node0;
  · 执行 E item = p.item;,item = null
  · if (item != null && p.casItem(item, null)) 不满足
  · 执行 else if ((q = p.next) == null),q = node1,条件不满足
  · 执行 else if (p == q),条件不满足
  · 执行 p = q;,p = node1
  第二次循环:
  · head = node0, h = node0, p = node1;
  · 执行 E item = p.item;,item = node2
  · if (item != null && p.casItem(item, null)), item != null 满足,如果CAS操作成功
  p != h 成立,调用updateHead
  执行 updateHead(h, ((q = p.next) != null) ? q : p); 之后,q = node2
  在updateHead里面
  h != p 成立,如果CAS操作成功(将head设置为node2)
  执行 h.lazySetNext(h);,这个时候 h = node0,这个方法执行完之后,node0.next = node0
  · 将item返回
  这个时候队列是图中第二种情况,线程A结果为:
  head = node2
  tail = node0
  t = node0
  p = node0
  q = node0.next = node0
  看到结果了吧,这个时候 p = q = node0 !其实主要原因是在 updateHead方法的 h.lazySetNext(h) 操作里面,将旧的head.next设置成为了自己即 head.next = head。但是要注意:是旧的head
  从上面分析的过程要注意:
  1、多线程执行环境,单线程下一定不会出现这种情况
  2、注意引用赋值比如 Node<E> q = p.next,q指向的是p.next,虽然目前 p.next = node1,但是当p.next指向变了之后,q也跟着变了
  3、再是阅读源码的时候一定要弄清楚调用的每个方法的作用,这样才能对整个方法有一个准确的理解,比如这里的 h.lazySetNext(h);