2011-11-04 18 views
6

जावाडोक के अनुसार, यदि मैं javax.jms पर प्राप्त() को कॉल करता हूं। मैसेजकंस्यूमर यह संदेश तब तक अनिश्चित काल तक अवरुद्ध होगा जब तक कि संदेश उपभोक्ता बंद न हो जाए।javax.jms.MessageConsumer प्राप्त होने पर प्राप्त होता है जब उपभोक्ता

मेरे पास एक धागा है जिसमें एक प्राप्त() कहा जा रहा है। थ्रेड शट डाउन के हिस्से के रूप में मैं करीबी() को कॉल कर रहा हूं, लेकिन उपभोक्ता अभी भी प्राप्त करने में अवरुद्ध है() और इसलिए थ्रेड बंद नहीं होगा। मेरे कोड का सार है:

public String receiveMessage() { 
... 
... 
    System.out.println("About to receive") 
    TextMessage message = (TextMessage) consumer.receive(); 
    System.out.println("No longer receiving") 
... 
... 
} 

public void stop() { 
    try { 
     if (consumer != null) { 
      consumer.close(); 
     } 
    } catch (JMSException ex) { 
     throw new IllegalStateException(ex); 
    } 
} 

डिबगर में मैं करीब से देख सकते हैं() बुलाया जा रहा है, लेकिन अभी भी अवरोधों का सामना करते। यदि मैं टाइमआउट के साथ प्राप्त() विधि का उपयोग करता हूं तो यह टाइमआउट समाप्त होने तक अवरुद्ध हो जाएगा।

सबकुछ मेरे लिए सही दिखता है, उम्मीद है कि कोई मुझे बता सकता है कि मैं क्या गलत कर रहा हूं।

+0

जेएमएस अंतर्निहित कार्यान्वयन के लिए कुख्यात रूप से विशिष्ट है। यह मदद करेगा अगर आपने कहा कि आप किस का उपयोग कर रहे थे। – skaffman

+0

जवाब देने के लिए धन्यवाद। यह आईबीएम एमक्यू 7.0.0.2 – DaveRlz

+0

[प्राप्तNoWait] (http://docs.oracle.com/javaee/1.4/api/javax/jms/MessageConsumer.html#receiveNoWait()) –

उत्तर

5

मैंने समस्या हल की है, मैं कनेक्शन नहीं कर रहा था .start() कहीं भी। एक बार जब मैंने इसे डाल दिया, तो MessageConsumer.receive() ने इसे बंद करते समय अवरुद्ध करना बंद कर दिया और जैसा कि मैंने अपेक्षा की थी, सबकुछ काम करता था।

आपके सुझावों के लिए धन्यवाद।

2
  1. receive(long timeout) प्रयास करें, और भूल नहीं है की जाँच करने के लिए है कि वापस आ mesage null नहीं है।
  2. consumer.close() के अलावा आप मतदान थ्रेड को भी बाधित कर सकते हैं - यदि close() खराब तरीके से लागू किया गया है और अवरुद्ध रिसीवर को सूचित नहीं करता है, तो यह जाग जाएगा।
+0

इसके लिए धन्यवाद। मैंने प्राप्त करने के टाइमआउट संस्करण को आजमाया है() और मुझे एक ही समस्या है - यह सिर्फ टाइमआउट के बाकी हिस्सों के लिए अवरुद्ध है और इसलिए मेरा ऐप टाइमआउट पूरा होने तक बंद नहीं होगा, जो कि मैं बिल्कुल नहीं चाहता हूं। – DaveRlz

+0

हाँ, एक और बात - अगर वह पूरे ऐप को बंद करने का हिस्सा है, तो ऑब्जेक्ट्स का पूरा सेट बंद करें ('संदेशकंस',' सत्र ',' कनेक्शन')। –

4

एक और विचार।

जेएमएस में, कनेक्शन बहु-थ्रेडेड है। सत्र और नीचे (उपभोक्ता, निर्माता, संदेश, आदि) are not thread-safe। यदि आप कई धागे से उस गैर-थ्रेड-सुरक्षित सामग्री तक पहुंच रहे हैं, तो आप बहु-थ्रेडेड एक्सेस से बचने के लिए ज़िम्मेदार हैं।

नीचे दिखाया गया कोड ऐसा लगता है कि आप उपभोक्ता पर कुछ धागे से विधियों को कॉल कर रहे हैं। उस नियम का उल्लंघन।

कनेक्शन ऑब्जेक्ट को बंद करना सुरक्षित हो सकता है। कोई थ्रेडिंग टकराव नहीं है और कोई समझदार कार्यान्वयन डब्ल्यू/कनेक्शन से जुड़े संसाधनों को साफ करने के लिए सही काम करेगा।

+0

+1 - टिप के लिए धन्यवाद। – DaveRlz

2

लेकिन फिर भी, उपभोक्ता.क्लोज़() को किसी अन्य थ्रेड पर कॉल करना सही काम नहीं है। आपको एक कनेक्शन करने की आवश्यकता होगी। बंद करें जो उस कनेक्शन के तहत सभी सत्रों, उपभोक्ताओं, उत्पादकों आदि को बंद करने का ख्याल रखेगा।

संबंधित मुद्दे

 संबंधित मुद्दे