An unbounded blocking queue that uses the same ordering rules as class and PriorityQueue
supplies blocking retrieval operations. W Hile This queue is logically unbounded, attempted additions could fail due to resource exhaustion (causing OutOfMemoryError
).
The Priorityblockingqueue is a very basic priority queue that provides a blocking read operation on a priorityqueue basis. It is unrestricted, meaning that adding elements to the queue may fail (leading to ourofmemoryerror). The following is an example where objects in the priority queue are queued in order of precedence:
import java.util.arraylist;import java.util.list;import java.util.queue;import java.util.random;import java.util.concurrent.executorservice;import java.util.concurrent.executors; import java.util.concurrent.priorityblockingqueue;import java.util.concurrent.timeunit;class prioritizedtask implements runnable, comparable<prioritizedtask> { private static int counter = 1; private final Int priority; private random random = new random (47); private final int id = counter++;//This ID is not static, so protected static List<PrioritizedTask> sequence = new Arraylist<> (); public prioritizedtask (int priority) { This.priority = priority; sequence.add (This); } @Override public int compareto ( Prioritizedtask o) { int val = This.priority - o.priority; //higher value, higher priority return val < 0 ? 1 : (val > 0 ? -1 : 0); } @Override public void run () { try { TimeUnit.MILLISECONDS.sleep (Random.nextint ()); } catch (interruptedexception e)   { } System.out.println (This); } @Override Public string tostring () { return String.Format ("p=[%1$-3d]", priority) + ", id=" &NBSP;+&NBSP;ID;&NBSP;&NBSP;&NBSP;&NBSP;} public static class EndFlagTask extends PrioritizedTask { private executorservice exec; public endflagtask (Executorservice executorservice) { super (-1);//Lowest priority exec = executorService; } @Override public void run () { system.out.println (this + " calling shutdownnow ()"); exec.shutdownnow (); } }}class prioritizedtaskproducer implements runnable { private queue <Runnable> queue; private ExecutorService exec; public prioritizedtaskproducer (queue<runnable> queue, executorservice exec) { this.queue = queue; this.exec = exec; } @Override publIc void run () { try { //slowly add high-priority tasks for (int i = 0; i < 6; i++) { TimeUnit.MILLISECONDS.sleep (+); queue.add (New prioritizedtask (9)); &NBSP;//6 Priority 10 } //first create a p=0 task queue.add (new Prioritizedtask (0)); queue.add (new prioritizedtask (0)); //adding low-priority tasks for (int i = 0; i < 6; i++) {// Priority 0-9 Queue.add (New prioritizedtask (i)); } //add a task to end the flag queue.add (New prioritizedtask.endflagtask (exec)); } catch (interruptedexception e) { // TODO: handle exception } system.out.println ("Finished prioritizedtaskproducer."); }}class PrioritizedTaskConsumer implements Runnable { private PriorityBlockingQueue<Runnable> queue; public Prioritizedtaskconsumer (Priorityblockingqueue<runnable> queue) { this.queue = queue; } @Override public void run () { try { //the task from the queue until exec stops. while (! Thread.interrupted ()) { //use the current thread to run these tasks &nBsp; queue.take (). Run (); } } catch ( Interruptedexception e) { } System.out.println ("Finished prioritizedtaskconsumer."); }}public final class PriorityBlockingQueueDemo { public static void main (String[] args) { executorservice exec = executors.newcachedthreadpool (); PriorityBlockingQueue<Runnable> queue = new Priorityblockingqueue<> (); exec.execute (New PriorItizedtaskproducer (queue, exec)); exec.execute (new Prioritizedtaskconsumer (queue)); }}
Execution Result:
P=[9], id=1p=[9], id=2p=[9], id=3p=[9], id=4p=[9], id=5finished prioritizedtaskproducer.p=[9], ID=6P=[5], ID =14P=[4], id=13p=[3], id=12p=[2], id=11p=[1], id=10p=[0], id=7p=[0], id=9p=[0], id=8p=[-1], id=15 calling S Hutdownnow () finished Prioritizedtaskconsumer.
The creation sequence of the Prioritizedtask object is recorded in the sequencelist for comparison with the actual order. The run () method sleeps for a short period of time and then prints the object information, and Endflagtask provides the ability to stop executorservice, to make sure it is the last object in the queue, so it has the lowest priority (-1, the higher the priority value, the higher the priority).
Prioritizedtaskproducer and Prioritizedtaskconsumer link to each other through Priorityblockingqueue. Because the blocking feature of this queue provides all the necessary synchronization, you should notice that there is no explicit synchronization required--regardless of whether there are elements when you read from this queue, because this queue will block the reader directly when there are no elements.
As you can see from the execution results, the first queue is the 6 task with priority 9, because these tasks are created first.
Finished prioritizedtaskproducer.
The printing of this sentence indicates that the producer has put all the tasks into the queue, because the task is placed in the queues and the task is extracted from the queue and executed two different tasks (i.e., producer and consumer), so producer first outputs "finished Prioritizedtaskproducer. ". In the output of this sentence, there are only 5 p=9 tasks in front of the queue, so there are 1 p=9 tasks are not out of line, but also follow up into various tasks. Due to the tasks in the queue, the priority p highest is p=9, so the 6th p=9 task first out of the queue. The remaining tasks are sorted by the size of P.
The ID property of the task represents the order in which they were created, because the ID is incremented, and the ID increases for each task created. So from
P=[5], id=14
It is clear that the p=5 task, which has the largest ID, is the last to be created. As can be seen from our code, P=5 's task is indeed the last to be created.
It can also be seen that when P is the same, the order in which the queue is out is indeterminate, for example:
P=[0], id=7p=[0], id=9p=[0], id=8
In addition, when using this class, you need to be aware of:
This class does not permit null
elements. A Priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so results in ClassCastException
).
The priorityblockingqueue of Java concurrency New component