★
队列概念
Queue接口与List、Set为同级别,都为Collection接口子接口。除了拥有 Collection 接口基本操作外,队列还提供其他的插入、提取和检查操作。每个方法都存在两种形式:一种抛出异常(操作失败时),另一种返回一个特殊值(null 或 false,具体取决于操作)。插入操作的后一种形式是用于专门为有容量限制的 Queue 实现设计的;在大多数实现中,插入操作不会失败。
非阻塞队列:
ConcurrentLinkedQueue
传统的Queue在面对多线程情况下,是无法达到线程安全的,解决该问题的方法有几种,加锁Synchronized可以解决,但是效率比较低,这里我们使用ConcurrentLinkedQueue来解决。
1.字段:
头节点和尾节点
private transient volatile Node<E> head;
private transient volatile Node<E> tail;
节点:
private static class Node<E> {
volatile E item;
volatile Node<E> next;
...
}
该内容比较简单,重点是在入队和出队操作上面
2.入队列
将新节点,防止到队列尾部,将tail指针更新到队列尾部,注意在多线程情况下,普通的入队,可能就会出现插队情况。
由于高并发,所以head节点和tail节点并不是十分的精确,所以tail可能指向的是倒数第二个节点。
多线程操作,没有上锁,注意中间随时都有被挂起的可能!
public boolean offer(E e) {
checkNotNull(e);
final Node<E> newNode = new Node<E>(e); //将值包装成为一个新的节点
for (Node<E> t = tail, p = t;;) { //cas操作
Node<E> q = p.next;
if (q == null) { //判断P是tail节点
if (p.casNext(null, newNode)) { //cas,期待值是null,更新值是newNode
if (p != t) //首次添加,不跟新,所以tail可能并不是最后的节点
casTail(t, newNode); // 更新tail
return true;
}
// Lost CAS race to another thread; re-read next
}
else if (p == q)
p = (t != (t = tail)) ? t : head;
else //向队尾移动
p = (p != t && t != (t = tail)) ? t : q;
}
}
3.出队列
public E poll() {
restartFromHead:
for (;;) {
for (Node<E> h = head, p = h, q;;) {
//获取头节点的值
E item = p.item;
//cas操作将 头节点值设置为Null
if (item != null && p.casItem(item, null)) {
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) {
updateHead(h, p);
return null;
}
else if (p == q)
continue restartFromHead;
else
p = q;
}
}
}
4.size()
public int size() {
int count = 0;
for (Node<E> p = first(); p != null; p = succ(p))
if (p.item != null)
if (++count == Integer.MAX_VALUE)
break;
return count;
}
succ()
final Node<E> succ(Node<E> p) {
Node<E> next = p.next;
return (p == next) ? head : next;
}
5.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;
}
参考:https://www.jianshu.com/p/231caf90f30b