Search code examples
javaconcurrencyblockingqueueblockingcollection

Why hasn't the PriorityBlockingQueue queue to sort elements according to the priority


This my code ,the code run the end is not my excepted.

I think the PriorityBlockingQueue sorted by Priority but the end is not my expected,Who can told me why.

 public class TestPriorityQueue {  

    static Random r=new Random(47);  

    public static void main(String args[]) throws InterruptedException{  
        final PriorityBlockingQueue q=new PriorityBlockingQueue();  
        ExecutorService se=Executors.newCachedThreadPool();  
        //execute producer  
        se.execute(new Runnable(){  
            public void run() {  
                int i=0;  
                while(true){  
                    q.put(new PriorityEntity(r.nextInt(10),i++));  
                    try {  
                        TimeUnit.MILLISECONDS.sleep(r.nextInt(1000));  
                    } catch (InterruptedException e) {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    }  
                }  
            }  
        }); 

        //execute consumer  
        se.execute(new Runnable(){  
            public void run() {  
                while(true){  
                    try {  
                        System.out.println("take== "+q.take()+" left:== ["+q.toString()+"]");  
                        try {  
                            TimeUnit.MILLISECONDS.sleep(r.nextInt(1000));  
                        } catch (InterruptedException e) {  
                            // TODO Auto-generated catch block  
                            e.printStackTrace();  
                        }  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    }  
                }  
            }  
        });  
        try {  
            TimeUnit.SECONDS.sleep(5);  
        } catch (InterruptedException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        System.out.println("shutdown");  
    }  

}  

class PriorityEntity implements Comparable<PriorityEntity> {  
    private static int count=0;  
    private int id=count++;  
    private int priority;  
    private int index=0;  

    public PriorityEntity(int priority,int index) {  
        this.priority = priority;  
        this.index=index;  
    }  

    public String toString(){  
        return id+"* [index="+index+" priority="+priority+"]";  
    }  


    //数字大,优先级高  
  public int compareTo(PriorityEntity o) {  
      return this.priority < o.priority ? 1  
              : this.priority > o.priority ? -1 : 0;  
  }  
} 

The following are the results,I would be very grateful to you for your help

enter image description here


Solution

  • Some observations:

    1. in most cases the size of your queue was 1. Clearly, no sort order is relevant in any of those.
    2. In a few cases the queue size may have been two, and in no such case does the output insinuate that an element of lower priority was preferred. I stress the verb "insinuate" because...
    3. your code has no synchronized blocks so nothing prevents the following sequence of operations:

      q.take();     // consumer thread
      q.put();      // producer thread
      q.toString(); // consumer thread
      

      with the legitimate outcome of q.toString() showing an element of higher priority than was taken.