替代无限循环作为监听器

时间:2014-02-27 19:50:19

标签: java java-ee-6 ibm-midrange

好吧,也许这对我来说是一个小问题。但我想问一下这个问题。我有一个Java Web应用程序,它通过无限循环检查来自AS400的DataQueue。如果队列中有消息,它会将消息传递给MQ,如果没有,只需继续检查。

起初这是一个好主意,但似乎当我在WAS中部署这个Web应用程序(ServletContextListener)并启动它时,我无法阻止它。也许是因为它消耗了资源。

所以也许无限循环不是答案。您是否知道在AS400 DataQueue上不断检查新消息的方法?

3 个答案:

答案 0 :(得分:5)

您不需要经常检查或手动暂停..

您可以将超时值传递给read(),并且您的app / thread将在返回之前等待那么长的条目。如果你传递-1,它将永远等待......


http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/rzahh/dqconsumerexample.htm#dqconsumerexample

         // Read the first entry off the queue.  The timeout value is
         // set to -1 so this program will wait forever for an entry.
         System.out.println("*** Waiting for an entry for process ***");

         DataQueueEntry DQData = dq.read(-1);

         while (Continue)
         {

            // We just read an entry off the queue.  Put the data into
            // a record object so the program can access the fields of
            // the data by name.  The Record object will also convert
            // the data from server format to Java format.
            Record data = dataFormat.getNewRecord(DQData.getData());

            // Get two values out of the record and display them.
            Integer amountOrdered = (Integer) data.getField("QUANTITY");
            String  partOrdered   = (String)  data.getField("PART_NAME");

            System.out.println("Need " + amountOrdered + " of "
                               + partOrdered);
            System.out.println(" ");
            System.out.println("*** Waiting for an entry for process ***");

            // Wait for the next entry.
            DQData = dq.read(-1);
         }

答案 1 :(得分:3)

侦听器可能正在使用所有CPU,因为它尽可能快地循环。如果你用Thread.sleep来限制它,即使是几毫秒它也会有所帮助。

无论如何,在Java EE环境中,最好使用Message Driven Bean

http://docs.oracle.com/javaee/6/tutorial/doc/bncgl.html#bncgq

答案 2 :(得分:2)

DataQueue read()方法支持InterruptedException

这是一个使用带有中断阻塞来处理清除终止的消息的示例:

public class DataQueueMappingListener 
  implements ServletContextListener, Runnable {
    public static final int JOIN_TIMEOUT = 30000; // join timeout in millis
    private Thread mapper;

    public void contextInitialized(ServletContextEvent sce) {
        mapper = new Thread(this);
        mapper.setPriority(Thread.MIN_PRIORITY);
        mapper.start();
    }

    public void contextDestroyed(ServletContextEvent sce) {
        mapper.interrupt();
        try {
            mapper.join(JOIN_TIMEOUT);
        } catch (InterruptException e) {
            Thread.currentThread().interrupt();
        }
    }

    public void run() {
        AS400 as400 = new AS400(...);
        DataQueue dq = new DataQueue(as400, ...);
        while(!Thread.currentThread().isInterrupted()) {
            try {
                DataQueueEntry dqe = dq.read();
                if (dqe != null) map(dqe);
            } catch (Exception e) {
                Thread.currentThread().interrupt();
            }
        }
        as400.disconnectService(AS400.DATAQUEUE);
    }

    private void map(DataQueueEntry dqe) {
        // map to MQ here
    }
}

完整示例以GitHub Gist提供。