日期:2014-05-20  浏览次数:20790 次

关于PriorityQueue不得不说的事
写程序的时候,用多线程,想要实现根据线程中定义的一个权重值,来每次取出一个最小的,来操作。

想来,貌似是优先级队列,因此就用PriorityQueue来实现咯
本来想偷懒,可惜写完测得时候就出问题了·~~
当然,也许是我对这个类不是很熟造成的

疑问:1、PriorityQueue默认的排序是升序还是降序啊?
2、我在用PriorityQueue时,先new了一个实例,
PriorityQueue<TestThread> poolQueue=new PriorityQueue<TestThread>(5);
我想问下,这个对列能够使用自定义的Comparator?
3、我在向这个poolQueue中添加元素的时候~~~直接用的offer,所有new的TestThread的优先级初始都是一样的~~
可是我在offer第二个对象的时候就报错了·~~~
Exception in thread "main" java.lang.ClassCastException: TestThread cannot be cast to java.lang.Comparable
at java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:595)
at java.util.PriorityQueue.siftUp(PriorityQueue.java:591)
at java.util.PriorityQueue.offer(PriorityQueue.java:291)
at cn.gov.cma.ncc.dcmpp.dispatch.server.util.PrioritySortUtil.main(PrioritySortUtil.java:58)
这错貌似是因为不能对对象直接排序,默认的Comparator不支持。

第一次用这玩意·~~不太会,在此开贴求教!!

------解决方案--------------------
1、升序
2、可以,new PriorityQueue(5, new MyComparator());
3、因为你的对象没有实现Comparable或者传入Comparator

------解决方案--------------------
PriorityQueue与线程没有什么关系,用在哪里都可以。
你说,队列指定Comparator为SortUtil,我不知道你怎么写的。
Java code
PriorityQueue<MyThread> q = new PriorityQueue<MyThread>(10, new Comparator<MyThread>() {

    public int compare(MyThread o1, MyThread o2) {
        return o1.weight - o2.weight;
    }
    
});
q.offer(new MyThread(5));
q.offer(new MyThread(7));
q.offer(new MyThread(2));
q.offer(new MyThread(6));
q.offer(new MyThread(8));
System.out.println(Arrays.toString(q.toArray()));

------解决方案--------------------
PriorityQueue内部成员数组queue其实是实现了一个二叉树的数据结构,因此它的排序其实是排序的二叉树,因此它的树的根即第一个元素都是最小的元素 

当每次从PriorityQueue中取数据的时候,你会发现它后面几个元素的排序会变化的,而且都是有规律的
Java code

PriorityQueue<String> pq = new PriorityQueue<String>();
        pq.add("dog");
        pq.add("apple");
        pq.add("fox");
        pq.add("easy");
        pq.add("boy");
        //
        while(!pq.isEmpty()){
            for(String s:pq){
                System.out.print(s+" ");
            }
            System.out.println();
            System.out.println("Priority.poll() : "+pq.poll());
        }

------解决方案--------------------
无论你怎么顺序添加,PriorityQueue都会保证顺序取出的。这个你随便找个代码测试一下就行了(别用你自己的类,用什么String之类就非常清楚了)
------解决方案--------------------
你在多线程共享这个队列的情况下不能使用 PriorityQueue,而应该使用 PriorityBlockingQueue