我有一个 Struts2 Action 类,它为 JMS 队列中的贸易列表放置一个 JMS Fetch 请求。此 JMS Fetch 消息由外部进程处理,可能需要几秒钟甚至几分钟,具体取决于外部任务处理应用程序要处理的交易文件的数量。
我想知道如何用适当的响应来处理这个 HTTP 请求。客户是否等到交易列表返回?(客户端(UI)必须对其采取行动,同时无事可做)。
我接近它的方式是 HTTP Request --> Struts2 Action -->
- 调用 Runnable 以在单独的线程中运行(与 Action 类分开)
- 界面等待
- 动作类线程休眠直到可运行它的工作
- 任务完成后,将交易列表返回给 UI
流程如下:
- 将 JMS 获取请求放在 Queue1 上
Runnable 的 ExecutorService
CClass cclass = new CClass(); final ExecutorService execSvc = Executors.newFixedThreadPool(1); execSvc.execute(cclass);
CClass 实现 runnable 返回交易列表的地方:
List<Trade> tradesList = new ArrayList<Trade>();
@Override
public void run() {
while (true) {
try {
Message message = msgConsumer.receive(); // SYNCHRONOUS / NO MDB
if (message == null){
break;
}
if (message instanceof TextMessage) {
TextMessage txtMessage = (TextMessage) message;
Trade trade = TradeBuilder.buildTradeFromInputXML(txtMessage);
if (trade != null) {
tradesList.add(trade); // tradeList is a CClass class variable
}
}
} catch (JMSException e) {
logger.error("JMSException occurred ", e);
}
}
closeConnection();
}
当这个runnable正在执行时,我在Action类中做了一个Thread.sleep(让Runnable在单独的线程中执行)
// In Action class
try {
Thread.sleep(5000); // some time till when the runnable will get executed
} catch (InterruptedException e) {
e.printStackTrace();
}
execSvc.shutdown();
问题是如果我将 Callable 与 FutureTask 一起使用并执行 get() ,那将一直阻塞,直到返回任何结果。如果我执行 Runnable,我必须让 Action 类 Thread 进入休眠状态,直到 runnable 执行并且 tradeList 可用。
使用 Runnable 方法,我能够将几百条记录返回给 UI,在主 Action 类中提供 5 秒的 Thread.sleep(),但当要获取数千条记录并在 UI 中显示时,只能部分构建 tradeList。
这显然不是万无一失的方法。
有什么更好的建议方法吗?请在一个完整的请求 - 响应流中阐明处理步骤。