2011-07-28 23 views
0

1つのスレッドがメッセージを処理したときにjmsがメッセージを受け取るようにしたい(threadPoolが呼び出し可能にする)。 メッセージはマスタースレッドによって受信されます。JMSとThreadPoolの問題?

私は春3.0.5を使用します:マスタースレッドのウェイ1に

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()); 

を:

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
以下の優れている方法

あなたがしようとしていることを私は確信していません。複数のメッセージを同時に処理する場合は、JmsTemplateから離れてDefaultMessageListenerContainerconcurrentConsumersを使用してください。 JMS namespaceでも利用できます。例えば

、あなたがあなたの質問に表示しているすべてのコードを捨て、代わりにこれを使用することができると思わ:

<jms:listener-container concurrency="10"> 
    <jms:listener destination="some.queue" ref="fooService" method="handleNewFoo"/> 
</jms:listener-container> 

自動的に同時メッセージ処理のために10スレッドまで産卵すること。メッセージが入ると、ワーカースレッドの1つを使用して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が起動すると、JMSメッセージの送信を開始するBeanが挿入されます。上で説明したように、メッセージを消費してメッセージを生成する同じBeanに渡し、標準出力に出力するSpringメッセージリスナーもあります。

+0

私の消費者はただ一つのスレッドdispatches.Thenはサブスレッドがプロセスをやらせてみましょう。 – fjjiaboming

+0

@ user808032:そうですね、あなたはすでにSpringがしているものを書き直すようです。私は自分の答えを更新しました。見てみな。 –

+0

OH.So、10スレッドのクライアント接続は1つだけですか?ありがとう! – fjjiaboming

0

なぜMDPを使用していないのですか?あなたはSpringの機能を再現しているようです。

例MDP:

public class MyMDP implements MessageListener { 
    public void onMessage(Message message) { 
     if (message instanceof TextMessage) { 
      ...do whatever... 
     } 
    } 
} 
+0

私はSpring JMSをうまく認識しません。 – fjjiaboming

+0

多くのメッセージにサブスレッドが指定されていることを確認するにはどうすればよいですか?コードは次のようになります。新しいThumbConsumerTaskImpl(jmsTemplate、destination);サブスレッドでは:(TextMessage)jmsTemplate.receive(destination);およびMDP。 – fjjiaboming

+0

あなたの考えはとても良いです。 – fjjiaboming