1、remove方法
public boolean remove(Object o) {
if (o != null) {
Node<E> next, pred = null;
for (Node<E> p = first(); p != null; pred = p, p = next) {
boolean removed = false;
E item = p.item;
if (item != null) {
if (!o.equals(item)) {
next = succ(p);
continue;
}
removed = p.casItem(item, null);
}
next = succ(p);
if (pred != null && next != null) // unlink
pred.casNext(p, next);
if (removed)
return true;
}
}
return false;
}
2、初始化队列
3、线程过来
执行remove("王五")
1)点击下面的first()
for (Node<E> p = first(); p != null; pred = p, p = next) {
first()方法如下:
Node<E> first() {
restartFromHead:
for (;;) {
for (Node<E> h = head, p = h, q;;) {
boolean hasItem = (p.item != null);
if (hasItem || (q = p.next) == null) {
updateHead(h, p);
return hasItem ? p : null;
}
else if (p == q)
continue restartFromHead;
else
p = q;
}
}
}
这个方法跟peek()方法几乎一样,如果头节点的元素时null(哨兵节点),则移动到下一个节点,返回这个真正的头节点。
所以这行执行完后的图为
for (Node<E> p = first(); p != null; pred = p, p = next) {
2)item为李四
E item = p.item;
3)0是传入进来的“王五”,下面这个条件返回true
if (!o.equals(item)) {
3)下面这行代码是将next指向了p的下一个节点
next = succ(p);
final Node<E> succ(Node<E> p) {
Node<E> next = p.next;
return (p == next) ? head : next;
}
4)第二轮循环
continue;
5)这里是先执行 pred = p, p = next。然后再判断p != null是否成立
for (Node<E> p = first(); p != null; pred = p, p = next) {
6)item是王五
E item = p.item;
7)0是传入进来的“王五”,下面这个条件返回false
if (!o.equals(item)) {
8)这里是通过cas操作将对应的元素设置为null
removed = p.casItem(item, null);
9)
next = succ(p);
10)条件不成立
if (pred != null && next != null)
11)返回true
if (removed)
return true;