Java中的PriorityBlockingQueue
Java中的PriorityBlockingQueue是BlockingQueue接口的实现,并且是java.util.concurrent包的一部分。
PriorityBlockingQueue是一个无边界队列
PriorityBlockingQueue在逻辑上是无界的,这与ArrayBlockingQueue(有界队列)和LinkedBlockingQueue(有界)可选。
尽管PriorityBlockingQueue是无限制的,但其初始容量可以指定,如果未指定,则默认为11. 此初始容量控制用于在队列上存储元素的数组的大小。
请注意,尽管队列在逻辑上是不受限制的,但是尝试尝试添加可能会由于资源耗尽而失败(导致OutOfMemoryError)。
Java PriorityBlockingQueue构造函数
- PriorityBlockingQueue()创建一个具有默认初始容量(11)的PriorityBlockingQueue,该默认容量根据其自然顺序对元素进行排序。
- PriorityBlockingQueue(int initialCapacity)创建一个具有指定初始容量的PriorityBlockingQueue,该容量根据其自然顺序对元素进行排序。
- PriorityBlockingQueue(int initialCapacity,Comparator <?super E>比较器)创建一个具有指定初始容量的PriorityBlockingQueue,该容量根据指定的Comparator对其元素进行排序。
- PriorityBlockingQueue(Collection <?extended E> c)创建一个PriorityBlockingQueue,其中包含指定集合中的元素。
PriorityBlockingQueue是线程安全的
Java中的PriorityBlockingQueue是java.util.PriorityQueue类的线程安全变体,并提供阻塞检索操作。插入方法永远不会阻塞,因为队列不受限制。
PriorityBlockingQueue不允许为空
Java中的PriorityBlockingQueue不允许使用null元素。尝试添加,放置或者提供null时,它将引发NullPointerException。
public class PriorityBQ { public static void main(String[] args) { BlockingQueue bQueue = new PriorityBlockingQueue<>(); // putting null bQueue.add(null); } }
输出:
Exception in thread "main" java.lang.NullPointerException at java.base/java.util.concurrent.PriorityBlockingQueue.offer(PriorityBlockingQueue.java:480) at java.base/java.util.concurrent.PriorityBlockingQueue.add(PriorityBlockingQueue.java:464) at com.theitroad.programs.PriorityBQ.main(PriorityBQ.java:11)
PriorityBlockingQueue是一个有序队列
Java中PriorityBlockingQueue的主要功能是可以对该队列中的元素进行优先级排序。 PriorityBlockingQueue的元素是根据其自然顺序进行排序的,或者由队列构造时提供的Comparator进行排序,具体取决于所使用的构造函数。通过按照我们自己的比较逻辑对元素进行排序,可以对优先级队列中的元素进行优先级排序。依赖自然顺序的优先级队列也不允许插入不可比较的对象(这样做会导致ClassCastException)。
就指定的顺序而言,此队列的头是最小的元素。队列检索操作将轮询,删除,查看和访问元素,并访问队列开头的元素。
如果多个元素具有相同的优先级,则头部是那些元素之一,即关系被任意打破。
例如
public class PriorityBQ { public static void main(String[] args) { BlockingQueue<Integer> bQueue = new PriorityBlockingQueue<>(); // adding elements bQueue.add(10); bQueue.add(5); bQueue.add(1); bQueue.add(3); // retrieving (element at head of the queue) System.out.println("Element- " + bQueue.poll()); } }
输出:
Element- 1
如我们所见,此处未指定Comparator,因此对Integer的自然排序(升序)用于对PriorityBlockingQueue中的元素进行排序。
具有比较器的PriorityBlockingQueue
这是另一个Java示例,其中指定了Comparator来对PriorityBlockingQueue中的元素进行排序(降序)。
public class PriorityBQ { public static void main(String[] args) { BlockingQueue<Integer> bQueue = new PriorityBlockingQueue<>(10, new MyComparator()); // adding elements bQueue.add(10); bQueue.add(5); bQueue.add(1); bQueue.add(3); // retrieving (head of the queue) System.out.println("Element- " + bQueue.poll()); } } //Comparator class class MyComparator implements Comparator<Integer>{ @Override public int compare(Integer o1, Integer o2) { return o2.compareTo(o1); } }
输出:
Element- 10
使用Java中的PriorityBlockingQueue的生产者使用者实现
BlockingQueue实现被设计为主要用于生产者-消费者队列,因此让我们来看一个使用PriorityBlockingQueue的生产者-消费者示例。在示例中,创建了两个线程,一个是生产者线程,另一个是消费者线程。
import java.util.concurrent.BlockingQueue; import java.util.concurrent.PriorityBlockingQueue; public class PriorityBQ { public static void main(String[] args) { BlockingQueue<String> bQueue = new PriorityBlockingQueue<>(10); String[] Names = {"Krishna", "Madhusudan", "Muralidhar", "Jagannath"}; // Producer new Thread(()->{ for(int i = 0; i < Names.length; i++){ try { bQueue.put(Names[i]); System.out.println("Added to queue-" + Names[i]); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); // Consumer new Thread(()->{ for(int i = 0; i < Names.length; i++){ try { System.out.println("Consumer retrieved- " + bQueue.take()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } }
输出:
Added to queue-Krishna Added to queue-Madhusudan Added to queue-Muralidhar Added to queue-Jagannath Consumer retrieved- Jagannath Consumer retrieved- Krishna Consumer retrieved- Madhusudan Consumer retrieved- Muralidhar