在上文《10.并发包阻塞队列之arrayblockingqueue》中简要解析了arrayblockingqueue部分源码,在本文中同样要介绍的是java并发包中的阻塞队列linkedblockingqueue。arrayblockingqueue队列是由数组实现,而linkedblockingqueue队列的实现则是链表(单向链表)实现,所以在linkedblockingqueue有一个node内部类来表示链表的节点。
static final class node<e> { e item;//入队元素 node<e> next;//指向后继节点 node(e x) { item = x; } }
同样它也有3个构造方法,与arrayblockingqueue略有不同。
1 public linkedblockingqueue() { 2 this(integer.max_value)//默认构造容量为int型的最大值队列 3 } 4 public linkedblockingqueue(int capacity) { 5 if (capacity 1 (c ==
前两个remove和poll方法都是非阻塞的,对于take方法则是阻塞的,线程会一直阻塞直到线程非空或者非满,但是它在阻塞时能被线程中断返回。
public e take() throws interruptedexception { e x; int c = -1; final atomicinteger count = this.count; final reentrantlock takelock = this.takelock; take.lockinterruptibly();//可被线程中断返回地获取锁 try { while (count.get() == 0) {//队列数据为空 notempty.await();//休眠非空等待队列上的线程 } x = dequeuer();//此时非空等待队列上的线程被唤醒,队列数据不为空,出队 c = count.getanddecrement(); if (c > 1) notempty.signal();//唤醒非空等待队列上的线程 } finally { takelock.unlock(); } if (c == capacity) signalnotfull();//唤醒非满等待队列 return x; }
队列出队的最后一个方法来看上面出现的dequeue入队方法。
private e dequeue() { node<e> h = head;//头节点,为空 node<e> first = h.next; h.next = h;//此时没有节点指向头节点,便于gc head = first; e x = first.item; first.item = null; return x; }
最后一个方法size。
public int size() { return count.get();//和arrayblockingqueue类似,与concurrentlinkedqueue不同,没有遍历整个队列,而是直接返回count变量。此处的count是atomicinteger变量。 }
以上就是并发包阻塞队列之linkedblockingqueue的详细内容。
