为什么在不同的CPU上运行两个Queue侦听器需要比一个处理器更长的时间?

时间:2013-09-19 00:55:42

标签: java queue jms

我有2个程序和3个CPU。一个程序可以完成两件事。首先,它向JMS队列(XMLQueue)发送大约60k条消息。它做的第二件事是侦听不同的JMS队列(ResultQueue)并提取返回的数据并对其进行处理。该程序在CPU 1上运行。

第二个程序是验证程序。它从XMLQueue接收消息,进行一些验证,然后将结果发送到ResultQueue。每次该程序收到一条新消息时,它都会在另一个线程中处理该消息(最多可以显示一次运行的最大线程数)。如果最大值正在运行,它会在收到新消息之前等待一个人死亡。为了提高性能,我试图在2个CPU上运行这个程序,计算每个CPU是否完成了一半的工作,它应该将总处理时间从大约3小时减少到1.5,如果让它在3或4上运行则更少机器。

我的问题是,当验证器程序只在一个CPU上时,处理1000条消息大约需要200秒。当我添加第二个CPU时,需要500秒!我认为当我使用更多内存和更多处理器来完成这项工作时,有一些关于队列的事情我不能正确理解。有什么想法吗?

以下是完成收听的代码。会话设置为自动确认。

public void listen() {
    if(closed){
        throw new IllegalStateException("cannot listen to a closed connection");
    }
    try{
        boolean listening=true;
        while(listening){
            Message msg = mc.receive();
            System.out.println("Received message " + ++count );
            if (msg instanceof TextMessage){
                TextMessage tmsg = (TextMessage) msg;
                String xml = tmsg.getText();

                DataParser parser = new XmlParser("paths.properties");

                synchronized(tm){
                    while(tm.isFull()){
                        try{

                            tm.wait();

                        }catch(InterruptedException e){
                            e.printStackTrace();
                        }
                    }
                    new Executor(xml, tm,parser,responder);
                    tm.notifyAll();
                }
            }
            else if (msg instanceof ObjectMessage){
                closeConnection();
                closed = true;
                listening=false;
            }
        }
    }catch(Exception e){
        e.printStackTrace();
    }


}

2 个答案:

答案 0 :(得分:0)

消息已经在某种程度上“天生地”并行。

因此,请尝试删除多线程代码并替换它

  • 使用多个程序实例,在队列中使用简单的侦听器。
  • 一个程序使用多个线程。每个线程再次侦听队列。您的方法的不同之处在于预先有多个听众。

这两种方法都不需要在处理期间管理(创建/同步)侦听器中的线程,因为处理线程在消息到达时已经存在。

答案 1 :(得分:0)

事实证明,发布的代码没有问题。我正在处理的验证是调用数据库。由于我有多个线程和多台机器调用同一个数据库,因此性能大大降低。通过在每台机器上预先缓存所需的表来解决问题。