好吧,也许这对我来说是一个小问题。但我想问一下这个问题。我有一个Java Web应用程序,它通过无限循环检查来自AS400的DataQueue。如果队列中有消息,它会将消息传递给MQ,如果没有,只需继续检查。
起初这是一个好主意,但似乎当我在WAS中部署这个Web应用程序(ServletContextListener)并启动它时,我无法阻止它。也许是因为它消耗了资源。
所以也许无限循环不是答案。您是否知道在AS400 DataQueue上不断检查新消息的方法?
答案 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提供。