## 1. 数据结构

// head.item == null
// last.next == null
private transient Node<E> last;

private static class Node<E> {
E item;
Node<E> next;
}


public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}

if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
last = head = new Node<E>(null);
}


## 2. 基于 ReentrantLock 的实现

private final ReentrantLock takeLock = new ReentrantLock();
// 集合已空则调用notEmpty.await，等集合添加元素后调用notEmpty.singal
private final Condition notEmpty = takeLock.newCondition();

private final ReentrantLock putLock = new ReentrantLock();
// 集合已满则调用notFull.await，等集合取出元素后调用notFull.singal
private final Condition notFull = putLock.newCondition();


## 3. 入队 offer

// offer 非阻塞
public boolean offer(E e) {
if (e == null) throw new NullPointerException();
final AtomicInteger count = this.count;
if (count.get() == capacity)
return false;
// 1. c表示插入前元素的个数
int c = -1;
Node<E> node = new Node<E>(e);
final ReentrantLock putLock = this.putLock;
putLock.lock();
try {
// 2. 元素入队有2个操作：一是元素添加到last.next并更新last；
//    二是唤醒阻塞的put操作继续添加元素(只有put时会阻塞notFull.await)
if (count.get() < capacity) {
// 2.1 元素入队
enqueue(node);
// 2.2 c表示插入前元素的个数
c = count.getAndIncrement();
// 2.3 集合未满，唤醒put操作，继续添加元素
if (c + 1 < capacity)
notFull.signal();
}
} finally {
putLock.unlock();
}
// 3. 插入前集合为空，则唤醒take操作，可以取元素了
if (c == 0)
signalNotEmpty();
return c >= 0;
}


private void enqueue(Node<E> node) {
// assert last.next == null;
last = last.next = node;
}


## 4. 出队 poll

// poll 非阻塞
public E poll() {
final AtomicInteger count = this.count;
if (count.get() == 0)
return null;
E x = null;
// 1. poll操作前元素的个数
int c = -1;
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
try {
//    二是唤醒阻塞的take操作继续取出元素(只有take时会阻塞notEmpty.await)
if (count.get() > 0) {
x = dequeue();
// 2.2 c为poll前元素的个数
c = count.getAndDecrement();
// 2.3 集合中元素不为空，唤醒take操作，断续取元素
if (c > 1)
notEmpty.signal();
}
} finally {
takeLock.unlock();
}
// 3. 取元素前集合已满，则唤醒put操作，可以继续添加元素
if (c == capacity)
signalNotFull();
return x;
}


private E dequeue() {
Node<E> first = h.next;
h.next = h; // help GC
E x = first.item;
first.item = null;
return x;
}


## 5. 删除元素 remove

// 删除指定 value 的元素
public boolean remove(Object o) {
if (o == null) return false;
fullyLock();
try {
for (Node<E> trail = head, p = trail.next;
p != null;
trail = p, p = p.next) {
if (o.equals(p.item)) {
// 删除指定节点 p，其中 trail 为 p 的前驱节点
return true;
}
}
return false;
} finally {
fullyUnlock();
}
}

// 删除指定节点 p，其中 trail 为 p 的前驱节点
// 注意 p.next 没变
void unlink(Node<E> p, Node<E> trail) {
// assert isFullyLocked();
// p.next is not changed, to allow iterators that are
// traversing p to maintain their weak-consistency guarantee.
p.item = null;
trail.next = p.next;
if (last == p)
last = trail;
if (count.getAndDecrement() == capacity)
notFull.signal();
}


## 5. 将集合中的元素取出 drainTo

// 将集合中的全部元素取出到集合 c 中
public int drainTo(Collection<? super E> c) {
return drainTo(c, Integer.MAX_VALUE);
}

// 将集合中的 maxElements 个元素取出到集合 c 中
public int drainTo(Collection<? super E> c, int maxElements) {
if (c == null)
throw new NullPointerException();
if (c == this)
throw new IllegalArgumentException();
if (maxElements <= 0)
return 0;
boolean signalNotFull = false;
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
try {
int n = Math.min(maxElements, count.get());
// count.get provides visibility to first n Nodes
int i = 0;
try {
while (i < n) {
Node<E> p = h.next;
p.item = null;
h.next = h;
h = p;
++i;
}
return n;
} finally {
if (i > 0) {
// assert h.item == null;
}
}
} finally {
takeLock.unlock();
if (signalNotFull)
signalNotFull();
}
}


posted on 2019-05-26 08:58  binarylei  阅读(167)  评论(0编辑  收藏  举报