0

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

wanghao
  • 271
  • 1
  • 7
  • 21
  • 3
    In each case, the one with the highest priority was take. Can you explain what you found unexpected? – Peter Lawrey Aug 27 '15 at 12:41
  • 1
    You can't take an element you have already taken, you can't take an element you haven't added. You can only chose from the elements in the queue and usually this is 1. I suggest adding 2-3 random elements before you start the test to see something more interesting. – Peter Lawrey Aug 27 '15 at 12:54
  • Thank you I already understand – wanghao Aug 28 '15 at 04:00

1 Answers1

5

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.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436