Skip to content

Commit f7a471e

Browse files
committed
[Optimization]
1.Split array blocking queue, linked blockinbg queue and Priority blocking queue files.
1 parent c87598c commit f7a471e

File tree

4 files changed

+191
-2
lines changed

4 files changed

+191
-2
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# ArrayBlockingQueue
2+
* ArrayBlockingQueue : 一个由数组支持的有界队列。
3+
* 如果到达了上界,将无法添加新的元素进入。
4+
* FIFO
5+
>ArrayBlockingQueue在构造时需要指定容量, 并可以选择是否需要公平性,如果公平参数被设置true,等待时间最长的线程会优先得到处理(其实就是通过将ReentrantLock设置为true来 达到这种公平性的:即等待时间最长的线程会先操作)。通常,公平性会使你在性能上付出代价,只有在的确非常需要的时候再使用它。它是基于数组的阻塞循环队 列,此队列按 FIFO(先进先出)原则对元素进行排序。
6+
```Java
7+
public boolean offer(E e) {
8+
checkNotNull(e);
9+
final ReentrantLock lock = this.lock;
10+
lock.lock(); //在写入的过程中获取锁
11+
try {
12+
if (count == items.length)
13+
return false;
14+
else {
15+
enqueue(e); //调用私有的enqueue方法
16+
return true;
17+
}
18+
} finally {
19+
lock.unlock(); //释放锁
20+
}
21+
}
22+
```
23+
```Java
24+
/**
25+
* Inserts element at current put position, advances, and signals.
26+
* Call only when holding lock.
27+
*/
28+
private void enqueue(E x) {
29+
// assert lock.getHoldCount() == 1;
30+
// assert items[putIndex] == null;
31+
final Object[] items = this.items;
32+
items[putIndex] = x;
33+
if (++putIndex == items.length)
34+
putIndex = 0;
35+
count++;
36+
notEmpty.signal(); //取消notEmpty的await.
37+
}
38+
```
39+
```Java
40+
public E poll() {
41+
final ReentrantLock lock = this.lock;
42+
lock.lock();
43+
try {
44+
return (count == 0) ? null : dequeue(); //判断当前队列有没有元素。有的话调用deqeueu方法。
45+
} finally {
46+
lock.unlock();
47+
}
48+
}
49+
```
50+
```Java
51+
private E dequeue() {
52+
// assert lock.getHoldCount() == 1;
53+
// assert items[takeIndex] != null;
54+
final Object[] items = this.items;
55+
@SuppressWarnings("unchecked")
56+
E x = (E) items[takeIndex];
57+
items[takeIndex] = null;
58+
if (++takeIndex == items.length)
59+
takeIndex = 0;
60+
count--;
61+
if (itrs != null)
62+
itrs.elementDequeued();
63+
notFull.signal();
64+
return x;
65+
}
66+
```
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# LinkedBlockingQueue
2+
* 一个由链接节点支持的可选有界队列。
3+
* 内部维护了一个Node类
4+
>LinkedBlockingQueue的容量是没有上限的(说的不准确,在不指定时容量为Integer.MAX_VALUE,不要然的话在put时怎么会受阻呢),但是也可以选择指定其最大容量,它是基于链表的队列,此队列按 FIFO(先进先出)排序元素。
5+
```Java
6+
static class Node<E> {
7+
E item;
8+
9+
/**
10+
* One of:
11+
* - the real successor Node
12+
* - this Node, meaning the successor is head.next
13+
* - null, meaning there is no successor (this is the last node)
14+
*/
15+
Node<E> next;
16+
17+
Node(E x) { item = x; }
18+
}
19+
```
20+
```Java
21+
public boolean offer(E e) {
22+
if (e == null) throw new NullPointerException();
23+
final AtomicInteger count = this.count; //此处的count为AtomicInteger,维护了原子性
24+
if (count.get() == capacity)
25+
return false;
26+
int c = -1;
27+
Node<E> node = new Node<E>(e);
28+
final ReentrantLock putLock = this.putLock;
29+
putLock.lock();
30+
try {
31+
if (count.get() < capacity) {
32+
enqueue(node);
33+
c = count.getAndIncrement();
34+
if (c + 1 < capacity)
35+
notFull.signal();
36+
}
37+
} finally {
38+
putLock.unlock();
39+
}
40+
if (c == 0)
41+
signalNotEmpty();
42+
return c >= 0;
43+
}
44+
45+
private void enqueue(Node<E> node) {
46+
// assert putLock.isHeldByCurrentThread();
47+
// assert last.next == null;
48+
last = last.next = node; //在链表的结尾,添加要插入的结点。
49+
}
50+
```
51+
```Java
52+
public E poll() {
53+
final AtomicInteger count = this.count;
54+
if (count.get() == 0)
55+
return null;
56+
E x = null;
57+
int c = -1;
58+
final ReentrantLock takeLock = this.takeLock;
59+
takeLock.lock();
60+
try {
61+
if (count.get() > 0) {
62+
x = dequeue();
63+
c = count.getAndDecrement();
64+
if (c > 1)
65+
notEmpty.signal();
66+
}
67+
} finally {
68+
takeLock.unlock();
69+
}
70+
if (c == capacity)
71+
signalNotFull();
72+
return x;
73+
}
74+
```
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# PriorityBlockingQueue
2+
* 一个由优先级堆支持的无界优先级队列。
3+
>PriorityBlockingQueue是一个带优先级的 队列,而不是先进先出队列。元素按优先级顺序被移除,该队列也没有上限(看了一下源码,PriorityBlockingQueue是对 PriorityQueue的再次包装,是基于堆数据结构的,而PriorityQueue是没有容量限制的,与ArrayList一样,所以在优先阻塞 队列上put时是不会受阻的。虽然此队列逻辑上是无界的,但是由于资源被耗尽,所以试图执行添加操作可能会导致 OutOfMemoryError),但是如果队列为空,那么取元素的操作take就会阻塞,所以它的检索操作take是受阻的。另外,往入该队列中的元 素要具有比较能力。
4+
```Java
5+
public boolean offer(E e) {
6+
if (e == null)
7+
throw new NullPointerException();
8+
final ReentrantLock lock = this.lock;
9+
lock.lock();
10+
int n, cap;
11+
Object[] array;
12+
while ((n = size) >= (cap = (array = queue).length))
13+
tryGrow(array, cap);
14+
try {
15+
Comparator<? super E> cmp = comparator;
16+
if (cmp == null)
17+
siftUpComparable(n, e, array);
18+
else
19+
siftUpUsingComparator(n, e, array, cmp);
20+
size = n + 1;
21+
notEmpty.signal();
22+
} finally {
23+
lock.unlock();
24+
}
25+
return true;
26+
}
27+
```
28+
29+
30+
31+
32+
33+
34+
35+
36+
37+
38+
39+
40+
41+
42+
43+
44+
45+
46+
47+
48+

DataStructrue/Queue/QueueConclusion.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Queue Conclusion
2-
2+
* Queue家族的继承关系:
3+
![Queue hierarchy](https://i.imgur.com/SrKTwOh.png)
34
### Queue interface
45
> `boolean add(E e);` Add and offer are used to add element into the queue.
56
>
@@ -9,7 +10,7 @@
910
>
1011
> `E poll();`
1112
>
12-
> `E element();` Retrieves, but does not remove, the head of this queue.
13+
> `E element();` Retrieves, but does not remove the head of this queue.
1314
>
1415
> `E peek();`
1516

0 commit comments

Comments
 (0)