2012-06-26 27 views
7

मेरी समझ के अनुसार, एक सर्वलेट कंटेनर servlets के सीमित उदाहरण और प्रत्येक सर्वलेट उदाहरण के एकाधिक धागे बनाता है और उन धागे और उदाहरणों का पुन: उपयोग करता है।ईजेबी थ्रेड सुरक्षित और सर्लेट क्यों नहीं हैं?

क्योंकि धागे के कई उदाहरण हैं, वे "थ्रेड-सुरक्षित" नहीं हैं (हालांकि मैं समझता हूं कि थ्रेड-सुरक्षा के साथ उन्हें कोड करना मुश्किल नहीं है)।

दूसरी ओर ईजेबी कंटेनर ईजेबी के धागे नहीं बनाते हैं, लेकिन केवल ईजेबी ऑब्जेक्ट्स का उपयोग करते हैं (पूल का उपयोग करके)। चूंकि ईजेबी उदाहरण के कई धागे नहीं हैं, इसलिए थ्रेड सुरक्षा का कोई सवाल नहीं है।

मेरा प्रश्न: अलग व्यवहार क्यों है? क्या ईजेबी को सर्वलेट्स (थ्रेड असुरक्षित) के रूप में काम करना अच्छा नहीं है?

मुझे यकीन है कि मुझे कुछ याद आ रहा है और वह गुम हिस्सा समझना चाहता हूं।

+0

उन्हें लगातार क्यों होना चाहिए? वे पूरी तरह से अलग चीजें करते हैं। – EJP

+0

@EJP, ठीक है, वे अलग-अलग उद्देश्य हल करते हैं, लेकिन उनके पास स्टेटलेसनेस के मामले में समानता है। इस समानता के साथ, ईजेबी केवल उदाहरण होने की बजाय धागे के द्वारा अधिक प्रदर्शन प्रभावी बना सकते थे। –

+0

यदि आप एक सर्वलेट/एक उदाहरण की चीजों में रुचि रखते हैं - तो आप इस पोस्ट को देखें: http://piotrnowicki.com/2012/04/one-servlet-instance-to-rule-them-all/ –

उत्तर

8

शायद क्योंकि वे एक ही लक्ष्य के साथ दिमाग में डिजाइन नहीं किए गए थे।

सर्वलेट एपीआई एक साधारण एपीआई है, जो HTTP प्रोटोकॉल के बहुत करीब है, जिस पर आप एप्लिकेशन या ढांचे का निर्माण कर सकते हैं। HTTP प्रोटोकॉल पूरी तरह से स्टेटलेस है, मुझे लगता है कि यह एक एपीआई बनाने के लिए समझ में आया है जो स्टेटलेस है। सर्वलेट एपीआई (उदाहरण के लिए स्ट्रिप्स) के शीर्ष पर बनाए गए कई ढांचे, प्रति अनुरोध एक्शन का एक उदाहरण उपयोग करते हैं, जिसका उपयोग समवर्ती रूप से नहीं किया जाता है।

ईजेबी एक अधिक जटिल और उच्च स्तरीय ढांचे हैं, जो यथासंभव लेनदेन संबंधी व्यवसाय-तर्क को लागू करने के लिए डिज़ाइन किए गए हैं। यह अधिक हेवीवेट है, और इसमें राज्य के घटक हैं। ये स्पष्ट रूप से थ्रेड-सुरक्षित होने की आवश्यकता है। मुझे लगता है कि यह स्टेटलेस बीन्स थ्रेड-सुरक्षित बनाने के लिए भी प्राकृतिक था।

यह ध्यान दिया जाना चाहिए कि उदाहरण के लिए, वसंत बीन्स डिफ़ॉल्ट रूप से सिंगलेट हैं, और इस प्रकार सर्वलेट के समान नियमों का पालन करना चाहिए। तो एक ही कार्यक्षमता कम या कम प्रदान करने के लिए कई डिज़ाइन संभव हैं।

थ्रेड के पास प्रदर्शन अनुकूलन के साथ कुछ लेना देना नहीं है। यदि आपको समसामयिक रूप से 3 अनुरोधों को संभालने की आवश्यकता है, तो आपको 3 धागे की आवश्यकता है, भले ही अनुरोध सर्वलेट या ईजेबी में हो।

+2

दोनों Servlets और EJB लेनदेन शुरू/प्रतिबद्ध कर सकते हैं और जावा ईई 6 के रूप में दोनों बहु-थ्रेडेड हो सकते हैं। यह सचमुच ईजेबी विशेषज्ञ समूह का मामला था जो सर्वलेट विशेषज्ञ समूह की तुलना में एक ही फैसले के साथ अधिक रूढ़िवादी है - पिछले कुछ सालों तक। ईजेबी 3.2 में हम पूरी तरह से उस फर्जी से छुटकारा पा रहे हैं "फाइलों का उपयोग नहीं कर सकते" प्रतिबंध जो कभी भी सिफारिश से अधिक नहीं होना चाहिए था और ईजेबी स्पेक की बजाय ईई स्पेक में होना चाहिए था। –

+0

विस्तृत स्पष्टीकरण के लिए धन्यवाद जेबी। मैं समझता हूं कि ईजेबी की तुलना में सर्वलेट आमतौर पर हल्के वजन वाले होते हैं। लेकिन दूसरी ओर, स्टेटलेस ईजेबी (जो ईजेबी के सबसे आम प्रकार हैं) समान कार्यक्षमता प्रदान करते हैं और किसी भी राज्य को स्टोर करने का अनुमान नहीं लगाते हैं। सर्वलेट्स के समान, ईजेबी आसानी से 'थ्रेड-सुरक्षित' होने के तरीके से लिखे जा सकते हैं। चूंकि, यह करने योग्य है, उदाहरण बनाने से थ्रेड बनाना अधिक प्रदर्शन प्रभावी है। क्या यह सही नहीं है? –

+2

सबसे पहले, स्टेटलेस बीन्स के पास राज्य हो सकता है। उनके पास बातचीत की स्थिति नहीं हो सकती है, जो बहुत अलग है। दूसरा, जैसा कि डेविड ब्लेविन्स ने अपने जवाब में बताया है, आप सिंगलेट्स का उपयोग कर सकते हैं, जो सर्वलेट के समान हैं। तीसरा, समवर्ती अनुरोधों को संभालने के लिए ईजेबी और सर्लेट में धागे का उपयोग किया जाता है। केवल अंतर यह है कि एक समेकित उदाहरण सभी समवर्ती धागे द्वारा उपयोग किया जाता है, जबकि एक ईजेबी का उपयोग केवल एक ही थ्रेड द्वारा किया जाता है। आपको लगता है कि एक बीन उदाहरण बनाने के लिए इतना महंगा क्यों है? जावा में ऑब्जेक्ट बनाना एक SQL क्वेरी निष्पादित करने से तीव्रता के कई ऑर्डर है, उदाहरण के लिए। –

3

आपका सर्वश्रेष्ठ उत्तर सीधे javax.servlet.SingleThreadedModel इंटरफेस के लिए जावाडोक से बाहर है:

पदावनत। जावा सर्वलेट एपीआई 2.4 के रूप में, कोई प्रत्यक्ष प्रतिस्थापन नहीं है।

public interface SingleThreadModel

सुनिश्चित करता है कि सर्वलेट्स एक समय में केवल एक अनुरोध को पूरा करने। इस इंटरफेस में कोई तरीका नहीं है।

यदि कोई सर्वलेट इस इंटरफ़ेस को लागू करता है, तो आप की गारंटी देते हैं कि सर्वलेट की सेवा विधि में कोई भी दो धागे निष्पादित नहीं होंगे। सर्वलेट कंटेनर सर्वलेट के एक उदाहरण, या सर्वलेट उदाहरणों के पूल को बनाए रखने और प्रत्येक नए अनुरोध को मुफ्त सर्वलेट में प्रेषित करके सिंक्रनाइज़ करके यह गारंटी कर सकता है।

ध्यान दें कि सिंगल थ्रेड मॉडेल सभी थ्रेड सुरक्षा समस्याओं को हल नहीं करता। उदाहरण के लिए, सिंगल थ्रेड मॉडेल सर्लेट का उपयोग होने पर भी, कई विशेषताओं पर एकाधिक अनुरोधों द्वारा सत्र विशेषताओं और स्थैतिक चरों को अभी भी एक्सेस किया जा सकता है।यह अनुशंसा की जाती है कि एक डेवलपर इस इंटरफेस को लागू करने के बजाय उन मुद्दों को हल करने के लिए अन्य साधन उठाए, जैसे किसी आवृत्ति चर के उपयोग से बचने या उन संसाधनों तक पहुंचने वाले कोड के ब्लॉक को सिंक्रनाइज़ करना। यह इंटरफ़ेस Servlet API संस्करण 2.4 में बहिष्कृत है।

8

अपने प्रश्न का सबसे छोटा जवाब निश्चित रूप से है यह एक अच्छा विचार है यह संभव है कि हम एक घटक कर सकते हैं कि वास्तव में जोड़ा EJBs सर्वलेट की तरह और EJB 3.1 में काम करने के लिए बनाने के लिए: @Singleton

एक @Singleton सेम एक सर्वलेट की तरह मल्टी-थ्रेडेड किया जा सकता है, या तो द्वारा:

  • तरीकों पर @ConcurrencyManagement(BEAN)
  • का उपयोग @ConcurrencyManagement(CONTAINER) का उपयोग करना @Lock(READ) के साथ जहां समरूपता वांछित है और @Lock(WRITE) उन विधियों पर है जो थ्रेड सुरक्षित नहीं हैं।

एक अन्य चीज जो Servlets के पास वर्षों से है कि ईजेबी कभी नहीं था <load-on-startup> जो एक सर्वलेट उत्सुकता से लोड करने और आवेदन शुरू करने पर काम करने की अनुमति देता है।

सर्वलेट <load-on-start> से मेल खाने के लिए हमने @Startup एनोटेशन जोड़ा जो किसी भी @Singleton ईजेबी में जोड़ा जा सकता है और एप्लिकेशन शुरू होने पर इसे शुरू करने का कारण बन जाएगा। इन बीन्स में @PostConstruct विधि होगी जब एप्लिकेशन शुरू होता है और उनके @PreDestroy को एप्लिकेशन बंद होने पर बुलाया जाता है।

एक नंबर (<load-on-startup>1</load-on-startup>) का उपयोग करने के बजाय जिस क्रम में सेम @Startup शुरुआत के साथ उसकी व्याख्या, आप @DependsOn साथ सेम व्याख्या और सेम एनोटेट सेम से पहले शुरू करने की आवश्यकता की एक सूची निर्दिष्ट कर सकते हैं हुक्म चलाना करने के लिए।

और Servlets और EJB को संरेखित करने के लिए हमने ईजेबी 3.1 में बहुत कम ज्ञात और समझा पहलू किया था, यह निश्चित रूप से .war फ़ाइलों के अंदर ईजेबी को पैक करने की अनुमति देने के लिए था - यह कम ज्ञात हिस्सा नहीं है - और जब हमने ऐसा किया सर्वलेट दृष्टिकोण से मेल खाने के लिए हमने चुपचाप java:comp/env की परिभाषा को बदल दिया।

ईजेबी 3.1 से पहले दो ईजेबी को java:comp/env नामस्थान (java:comp/env ईजेबी स्पेक में बीन-स्कॉप्ड) साझा करने का कोई संभावित तरीका नहीं था। इसके विपरीत, Servlets, व्यक्तिगत Servlets के लिए अपने निजी java:comp/env नामस्थान (java:comp/env Servlet spec में मॉड्यूल-स्कॉप्ड) के लिए कभी भी कोई रास्ता नहीं था। तो ईजेबी 3.1 में एक ईजेबी जो युद्ध में पैक किया गया है, वही मॉड्यूल-स्कॉप्ड java:comp/env वेबस्पेप में अन्य सभी Servlets और EJB के रूप में नामस्थान होगा, जो बीन-स्कॉप्ड java:comp/env नामस्थान के लिए एक बहुत बड़ा विपरीत है कि ईजेबी पैक होने पर प्राप्त होते हैं एक युद्ध के बाहर एक ईएआर। हमने उस पर हफ्तों तक बहस की।

अपने दोस्तों को प्रश्नोत्तरी करने के लिए बीयर-टाइम का मामूली थोड़ा सा मामूली।

+0

यह मेरे लिए अच्छी खबर है कि जेईई 6 में ईजेबी कई धागे का विकल्प प्रदान कर रहा है। यह मुझे खुश करता है कि मेरी समझ सही रास्ते पर है :) –