使用PriorityBlockingQueue时ClassCastException

时间:2017-07-10 21:01:13

标签: java multithreading message-queue

我正在尝试为我的游戏制作一个简单的消息管理器。但是,我得到以下例外:

Exception in thread "main" Exception in thread "Thread-4" java.lang.ClassCastException: MessageManagement.Message cannot be cast to java.lang.Comparable
at java.util.concurrent.PriorityBlockingQueue.siftUpComparable(Unknown Source)
at java.util.concurrent.PriorityBlockingQueue.offer(Unknown Source)
at java.util.concurrent.PriorityBlockingQueue.add(Unknown Source)
at MessageManagement.MessageManager.EnqueueMessage(MessageManager.java:69)

初始化代码是:

MessageManager messageManager = new MessageManager();
messageManager.start();

//send bootstrap message
CJournal.Journal(Main.class, "Testing messanger: ending bootstrapping message to messagemanager");
Message boot_strap_message = new Message();
boot_strap_message.mflag = EEventMachine.EM_BOOTSTRAP;
messageManager.EnqueueMessage(boot_strap_message);

实际的消息管理器是:

public  class MessageManager extends Thread {

    @Override
    public  void run() {
        // TODO Auto-generated method stub
        while (true)
        {

            if (!messagesQueue.isEmpty())
            {
                //pull message from queue
                Message message = messagesQueue.remove();

                //dispatch messages according to their type
                switch(message.mflag)
                {
                case EM_BOOTSTRAP:
                    CJournal.Journal(MessageManager.class, "Messaging system working properly.");
                default:
                    CJournal.Journal(MessageManager.class, "Dispatch Message Trashed");
                }
            }
        }
    }

    public static PriorityBlockingQueue<Message> messagesQueue = new PriorityBlockingQueue<Message>();

    public static void EnqueueMessage(Message message)
    {
        //Error happens here
        messagesQueue.add(message);
    }

为什么我收到此错误,我需要做些什么才能修复它?

2 个答案:

答案 0 :(得分:1)

PriorityBlockingQueue's javadoc

  

依赖于自然排序的优先级队列也不允许插入不可比较的对象(这样做会导致ClassCastException)。

您的Message课程需要实施Comparable

class Message implements Comparable<Message> {
    public int compareTo(Message m) {
        int comparisonResult = //comparison logic. 
        return comparisonResult;
    }
}

Comparable#compareTo个javadoc,compareTo

  

如果此消息小于,等于或大于(分别)指定的对象,则设置负整数,零或正整数。

您的另一个选择是向PriorityBlockingQueue提供Comparator

答案 1 :(得分:0)

Javadoc很清楚:

  

公共类PriorityBlockingQueue扩展了AbstractQueue   实现BlockingQueue,Serializable

     

一个无限制的阻塞队列,它使用与类相同的排序规则   PriorityQueue并提供阻塞检索操作。虽然这个   队列在逻辑上是无限制的,尝试添加可能由于失败而失败   资源耗尽(导致OutOfMemoryError)。这个课没有   允许null元素。依赖于自然排序的优先级队列   也不允许插入不可比较的对象(这样做   导致ClassCastException)

您必须实施Comparable界面。

class Message implements Comparable<Message> {

   public int compareTo( Message o ) {
      int diff = ...;
      return diff;
   }
}

或实现Comparator接口并将其提供给PriorityBlockingQueue的构造函数。

class MyComp implements Comparator<Message> {

   public int compare( Message l, Message r ) {
      int diff = ...;
      return diff;
   }
}