我希望jms在一个线程处理完一条消息时收到一条消息(threadPool提交一个可调用的)。 消息由主线程接收。 以下哪种方式更好:
我使用spring 3.0.5:
ApplicationContext context = new ClassPathXmlApplicationContext(
"application-context.xml");
jmsTemplate = (JmsTemplate) context.getBean("jmsTemplate");
destination = (Destination) context.getBean("destination");
_log4j.debug("ThreadSize in xml\t"
+ appConfig.getThumbCreatorThreadSize());
主线程中的方式1:
while (countFlag < 0) {
try {
TextMessage msg = (TextMessage) jmsTemplate
.receive(destination);
// prehandle ,then give to sub workers.
if (msg != null) {
_log4j.debug("JMSMessageID:\t" + msg.getJMSMessageID()
+ "\t" + msg.getText());
IConsumer thumbConsumerImpl = null;
thumbConsumerImpl = new ThumbConsumerTaskImpl(msg);
Future<List<ThumbCreatorInfo>> result = threadPool
.submit((Callable<List<ThumbCreatorInfo>>) thumbConsumerImpl);
}
} catch (IllegalArgumentException e) {
_log4j.warn(e.getMessage(), e);
} catch (JMSException e) {
_log4j.error("Please check the queue server!JMSException!", e);
} catch (Exception e) {
_log4j.error("", e);
}
}
主线程中的方式2:
TextMessage msg = (TextMessage) jmsTemplate.receive(destination);
do {
try {
// prehandle ,then give to sub workers.
if (msg != null) {
_log4j.debug("JMSMessageID:\t" + msg.getJMSMessageID()
+ "\t" + msg.getText());
IConsumer thumbConsumerImpl = null;
thumbConsumerImpl = new ThumbConsumerTaskImpl(msg);
Future<List<ThumbCreatorInfo>> result = threadPool
.submit((Callable<List<ThumbCreatorInfo>>) thumbConsumerImpl);
}
msg = (TextMessage) jmsTemplate.receive(destination);
} catch (IllegalArgumentException e) {
_log4j.warn(e.getMessage(), e);
} catch (JMSException e) {
_log4j.error("Please check the queue server!JMSException!", e);
} catch (Exception e) {
_log4j.error("", e);
}
} while (countFlag < 0);
答案 0 :(得分:0)
我不确定我得到了你想要做的事情。如果您尝试同时处理多个消息,请远离JmsTemplate并使用DefaultMessageListenerContainer和concurrentConsumers。也可以通过JMS namespace。
获取例如,您似乎可以丢弃您在问题中显示的所有代码并使用它代替:
<jms:listener-container concurrency="10">
<jms:listener destination="some.queue" ref="fooService" method="handleNewFoo"/>
</jms:listener-container>
这将自动生成多达10个线程以进行并发消息处理。当一条消息进来时,它将使用一个工作线程来调用fooService.handleNewFoo(),其中fooService是Spring上下文中的一个bean。
编辑:我在github上创建了一个示例项目,显示了一个基本的Spring JMS设置。您可以在https://github.com/zzantozz/testbed/tree/master/basic-spring-jms浏览源代码,或者只是克隆并运行它:
git clone git://github.com/zzantozz/testbed.git tmp
cd tmp
mvn compile exec:java -Dexec.mainClass=rds.jms.Main -pl basic-spring-jms
有一个主类启动JMS代理并启动Spring。当Spring启动时,它会启动一个开始发送JMS消息的bean。如上所述,还有一个Spring消息监听器,它使用消息并将它们传递给生成消息的同一个bean,然后将它们打印到stdout。
答案 1 :(得分:0)
你为什么不只是使用MDP?好像你正在重新创建Spring功能。
示例MDP:
public class MyMDP implements MessageListener {
public void onMessage(Message message) {
if (message instanceof TextMessage) {
...do whatever...
}
}
}