队列
想栈一样,队列(queue)也是表。然而,使用队列时插入在一端进行而删除在另一端进行,遵循先进先出,后进后出原则,就像排队一样
应用
1、打印机队列
2、还有之前线程里面讲到的,线程池的实现,有有界的和无界的阻塞队列
Java中队列的实现
其中ArrayBlockQueue的源码,在并发的时候已经介绍过了,可以参考https://blog.csdn.net/qq_22798455/article/details/81636772
ConcurrentLinkedQueue参考
https://blog.csdn.net/qq_22798455/article/details/81637397
看一下优先级队列
public PriorityBlockingQueue() {
this(DEFAULT_INITIAL_CAPACITY, null);
}
public PriorityBlockingQueue(int initialCapacity) {
this(initialCapacity, null);
}
//最终都是初始化这一个构造函数,通过一个Comparator来排列队列中的数据
public PriorityBlockingQueue(int initialCapacity,
Comparator<? super E> comparator) {
if (initialCapacity < 1)
throw new IllegalArgumentException();
this.lock = new ReentrantLock();
this.notEmpty = lock.newCondition();
this.comparator = comparator;
//数组实现
this.queue = new Object[initialCapacity];
}
//初始化一个传入collection的队列,若传入的集合本身就是有序的,
//比如说SortedSet一类的,那么就保留他的排序,若不是有序的,
//则按照Comparable自然的排序方法排序
public PriorityBlockingQueue(Collection<? extends E> c) {
this.lock = new ReentrantLock();
this.notEmpty = lock.newCondition();
boolean heapify = true; // true if not known to be in heap order
boolean screen = true; // true if must screen for nulls
if (c instanceof SortedSet<?>) {
SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
this.comparator = (Comparator<? super E>) ss.comparator();
heapify = false;
}
else if (c instanceof PriorityBlockingQueue<?>) {
PriorityBlockingQueue<? extends E> pq =
(PriorityBlockingQueue<? extends E>) c;
this.comparator = (Comparator<? super E>) pq.comparator();
screen = false;
if (pq.getClass() == PriorityBlockingQueue.class) // exact match
heapify = false;
}
Object[] a = c.toArray();
int n = a.length;
// If c.toArray incorrectly doesn't return Object[], copy it.
if (a.getClass() != Object[].class)
a = Arrays.copyOf(a, n, Object[].class);
if (screen && (n == 1 || this.comparator != null)) {
for (int i = 0; i < n; ++i)
if (a[i] == null)
throw new NullPointerException();
}
this.queue = a;
this.size = n;
if (heapify)
heapify();
}
public boolean add(E e) {
return offer(e);
}
public boolean offer(E e) {
if (e == null)
throw new NullPointerException();
final ReentrantLock lock = this.lock;
//加锁
lock.lock();
int n, cap;
Object[] array;
//若是当前数组的size已经要等于初始化queue的长度的时候,扩下容
while ((n = size) >= (cap = (array = queue).length))
//扩容操作,若是当前容量已经大于64,则扩容+2,若否,会扩容至现在的2倍
tryGrow(array, cap);
判断
try {
Comparator<? super E> cmp = comparator;
//优先使用传入的comparator
if (cmp == null)
siftUpComparable(n, e, array);
else
siftUpUsingComparator(n, e, array, cmp);
size = n + 1;
notEmpty.signal();
} finally {
lock.unlock();
}
return true;
}
public E poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return dequeue();
} finally {
lock.unlock();
}
}
private E dequeue() {
int n = size - 1;
if (n < 0)
return null;
else {
Object[] array = queue;
E result = (E) array[0];
E x = (E) array[n];
array[n] = null;
Comparator<? super E> cmp = comparator;
if (cmp == null)
siftDownComparable(0, x, array, n);
else
siftDownUsingComparator(0, x, array, n, cmp);
size = n;
return result;
}
}
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
E result;
try {
while ( (result = dequeue()) == null)
notEmpty.await();
} finally {
lock.unlock();
}
return result;
}
public E peek() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return (size == 0) ? null : (E) queue[0];
} finally {
lock.unlock();
}
}
栈和队列
1、栈、队列、优先级队列通常是用来简化某些程序操作的数据结构,而不是主要作为存储数据的。
2、在这些数据结构中,只有一个数据项可以被访问。
3、栈为先进后出,队列为先进先出
4、优先级队列是有序的插入数据,并且只能访问当前元素中优先级别最大(或最小)的元素。
5、这些数据结构都能由数组实现,但是可以用别的机制(后面讲的链表、堆等数据结构)实现。