public boolean add(E e) {
return true;
}

final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;//多线程情况下，如果业务系统没做并发控制，size的数量会远远大于实际元素的数量
modCount++;
}


List的变量size值为：88371
第2031个元素取出为null

return offer(e);
}

    public boolean offer(E e) {
checkNotNull(e);
final Node<E> newNode = new Node<E>(e);

for (Node<E> t = tail, p = t;;) {
Node<E> q = p.next;
if (q == null) {
// p is last node
if (p.casNext(null, newNode)) {
// Successful CAS is the linearization point
// for e to become an element of this queue,
// and for newNode to become "live".
if (p != t) // hop two nodes at a time
casTail(t, newNode);  // Failure is OK.
return true;
}
}
else if (p == q)
// We have fallen off list.  If tail is unchanged, it
// will also be off-list, in which case we need to
// reachable.  Else the new tail is a better bet.
p = (t != (t = tail)) ? t : head;
else
// Check for tail updates after two hops.
p = (p != t && t != (t = tail)) ? t : q;
}
}


接下来，我们再利用高并发queue对上面的demo进行改造，大家只要改变demo中的内容，讲下面两行的注释内容颠倒，即可发现没有丢失任何的元素：

再看一下高性能queue的poll()方法，才觉得NB，取元素的方法也用CAS实现了原子操作，因此在实际使用的过程中，当我们在不那么在意元素处理顺序的情况下，队列元素的消费者，完全可以是多个，不会丢任何数据：

    public E poll() {
for (;;) {
for (Node<E> h = head, p = h, q;;) {
E item = p.item;

if (item != null && p.casItem(item, null)) {
// Successful CAS is the linearization point
// for item to be removed from this queue.
if (p != h) // hop two nodes at a time
updateHead(h, ((q = p.next) != null) ? q : p);
return item;
}
else if ((q = p.next) == null) {
return null;
}
else if (p == q)
else
p = q;
}
}
}