java.util.PriorityQueue<E>
E 集合中所保存元素的类型。
public class PriorityQueue extends AbstractQueue implements Serializable
一个基于优先级堆的极大优先级队列。此队列按照在构造时所指定的顺序对元素排序,既可以 根据元素的自然顺序(Comparable)来指定排序,也可以根据Comparator来指定,这取决于使用那种构造方法。优先级队列不允许null元 素。依靠自然排序的优先级队列还不允许插入不可比较的对象,这样做可能导致ClassCastException。
此队列的头是按指定排序的最小元素。如果有多个元素都是最小值,则头是其中一个元素——选择方法是任意的。队列检索操作poll , remove , peek 和 element访问处于队列头的元素。
优先级队列是无界的,但是有一个内部容量,控制着用于存储队列元素的数组的大小。它总是至少与队列的大小相同。随着不断向优先级队列中添加元素,其容量会自动增加。无需指定容量增加策略的细节。
注意,此实现不是同步的。如果多个线程中的任意线程从结构上修改了列表,则这些线程不应同时访问PriorityQueue实例。相反,请使用线程安全的PriorityBlockingQueue类。
接口BlockingQueue<E>
public interface BlockingQueue<E> extends Queue<E>
支持两个附加操作的Queue,这两个操作是:检索元素时等待队列变为非空,以及存储元素时等待空间变得可用。
BlockingQueue不接受null元素。
BlockingQueue可以是限定容量的。
BlockingQueue实现主要用于生产者-使用者队列,但它另外还支持Collection接口。因此,举例来说,使用remove(x)从队列中移除任意一个元素是有可能的。然而,这种操作通常不会有效执行,只能有计划地偶尔使用,比如在取消排队信息时。
BlockingQueue实现是线程安全的。注意,BlockingQueue可以安全地与多个生产者和多个使用者一起使用。
class Producer implements Runnable { private final BlockingQueue queue; Producer(BlockingQueue q) { queue = q; } public void run() { try { while(true) { queue.put(produce()); } } catch (InterruptedException ex) { ... handle ...} } Object produce() { ... } } class Consumer implements Runnable { private final BlockingQueue queue; Consumer(BlockingQueue q) { queue = q; } public void run() { try { while(true) { consume(queue.take()); } } catch (InterruptedException ex) { ... handle ...} } void consume(Object x) { ... } } class Setup { void main() { BlockingQueue q = new SomeQueueImplementation(); Producer p = new Producer(q); Consumer c1 = new Consumer(q); Consumer c2 = new Consumer(q); new Thread(p).start(); new Thread(c1).start(); new Thread(c2).start(); } }
此接口是Java Collecitons Framework的成员。
类PriorityBlockingQueue
public class PriorityBlockingQueue<E> extends AbstractQueue<E> implments BlockingQueue<E> ,Serializable
一个无界的阻塞队列,它使用与类PriorityQueue相同的顺序规则,并且提供了 阻塞检索的操作。虽然此队列逻辑上是无界的,但是由于资源被耗尽,所以试图执行添加操作可能会失败,导致OutOfMemoryError。此类不允许使 用null元素,依赖自然顺序的优先级队列也不允许插入不可比较的对象。
如果需要有序的遍历,则应考虑使用Arrays.sort(pq.toArray())
接口Compara<T>
public interface Comparable<T>
此接口强行对实现它的每个类的对象进行整体排序。次排序被称为该类的自然排序,类的 compareTo方法被称为它的自然比较方法。实现此接口的对象列表和数组可以通过Collections.sort(和Arrays.sort)进行 自动排序。实现此接口的对象可以用作有序映射表中的键或有序集合中的元素,无需指定比较器。
阻塞队列的性能对比
主要是比较offer跟poll两个方法的性能,开N个线程,每个线程往队列里写或者取500个整数。线程数 20 50 100 200 500 1000
LinkedBlockingQueue 15,0 31,15 32,16 63,32 203,47 563,110
ArrayBlockingQueue 15,0 16,15 31,15 47,16 125,47 364,68
PriorityBlockingQueue 78,78 172,188 360,422 813,969 3094,2641 6547,5453
逗号前的数字是offer测试花费的时间,逗号后的数字是poll测试花费的时间。
结论:
1、ArrayBlockingQueue性能优于LinkedBlockingQueue,但是LinkedBlockingQueue是无界的。
2、ArrayBlockingQueue和LinkedBlockingQueue的poll方法总是比offer方法快,并发越高,差距越大
3、ArrayBlockingQueue和LinkedBlockingQueue的性能远高于PriorityBlockingQueue,显然优先队列在比较优先级上的操作上耗费太多
4、PriorityBlockingQueue的offer方法与poll方法的性能差距很小,基本维持在近似1:1