2009-03-05 18 views
46

साथ ही, क्या ऑब्जेक्ट सेट किया जा रहा है, यह सुनिश्चित करने के लिए कि हम सत्र में संग्रहीत ऑब्जेक्ट की स्थिति को जानते हैं, यह सुनिश्चित करने के लिए थ्रेड सुरक्षित होना चाहिए।क्या HttpSession थ्रेड सुरक्षित है, विशेषता थ्रेड सुरक्षित संचालन सेट/प्राप्त कर रहे हैं?

synchronized(session) { 
    session.setAttribute("abc", "abc"); 
} 

यह एक वैध सुझाव है:

इसके अलावा, मैं वेब कि कुछ उपयोग करने का सुझाव पर पढ़ रहा था?

उत्तर

34

नहीं, वे थ्रेड सुरक्षित नहीं हैं, आईबीएम - Java theory and practice: Are all stateful Web applications broken? के अनुसार। आपको सिंक्रनाइज़ करने की आवश्यकता है।

How HttpSession is not thread safe जावा रैंच से भी सहायक हो सकता है।

+3

लिंक पढ़ना चाहिए! ++ – cherouvim

+0

आप उन्हें सिंक्रनाइज़ क्यों करना चाहते हैं? प्रति क्लाइंट एक सत्र है और ग्राहक सिंगल थ्रेडेड नहीं हैं? – OscarRyz

+1

@ ऑस्कर रेयेस: एक ग्राहक कई समवर्ती अनुरोध जारी कर सकता है। उदाहरण के लिए CTRL + क्लिक करना (फ़ायरफ़ॉक्स पर) स्टैक ओवरफ्लो लोगो पर पागल की तरह। – cherouvim

4

नहीं। और चूंकि आप नहीं एक ही ग्राहक (सत्र) के साथ समवर्ती अनुरोध कर रही किया जाना चाहते हैं, तो आप इन अनुरोधों की तरह AbstractController वसंत MVC में करता है

+1

मुझे उदाहरण पसंद आया लेकिन अभी भी थोड़ा उलझन में है कि मैं अपने आवेदन के लिए इसका उपयोग कैसे करूंगा। –

2

कुछ मायनों में क्रमानुसार चाहिए, इस पर निर्भर करता है आपके ग्राहक डिजाइन।

क्या आपके पास एक ही क्लाइंट के लिए एक ही HTTP सत्र का उपयोग करके एकाधिक बकाया एक साथ अनुरोध करने के लिए, आपके वेब डिज़ाइन में अवसर है? ऐसा तब तक करना मुश्किल लगता है जब तक आप एक से अधिक HTTP सत्र को एकाधिक सॉकेट से जोड़ते हैं। (उर्फ, AJAX) ऐसा करने से कम, किसी दिए गए क्लाइंट की HTTP पहुंच एकल-थ्रेडेड होगी जहां तक ​​सर्वर का संबंध है, जिसका अर्थ है कि एक सत्र प्रभावी रूप से थ्रेड सुरक्षित है।

आपके सत्र ऑब्जेक्ट्स का सिंक्रनाइज़ेशन भविष्य में परिवर्तनों के विरुद्ध एप्लिकेशन को सुरक्षित बनाएगा जो आपके वेब एप्लिकेशन को एकाधिक एक साथ अनुरोध करने में सक्षम बनाता है, इसलिए यह एक बुरा विचार नहीं है। आधुनिक जावा कार्यान्वयन में, सिंक्रनाइज़ेशन में बड़ी लागत नहीं होती जो पहले इसके साथ जुड़ी थी, खासकर जब सिंक्रनाइज़ेशन आमतौर पर अनचाहे होता है। यदि आपका एप्लिकेशन AJAX का उपयोग करता है, जिसका अर्थ है कि आप अपने वेब सर्वर पर एकाधिक इन-फ्लाइट एक साथ अनुरोध की अपेक्षा करते हैं, तो सिंक्रनाइज़ेशन एक जरूरी है।

+0

मैं चीजों को गति देने के लिए AJAX अनुरोधों के लिए "सिंक्रनाइज़ ऑनऑशन" अक्षम करने के बारे में सोच रहा था (AJAX अनुरोध एक दूसरे के बाद एक दूसरे को निष्पादित कर रहे हैं, समानांतर में नहीं)। तो यह तब बड़ा नहीं है? मैंने सोचा कि यह AJAX के लिए सुरक्षित है क्योंकि काम प्रवाह आमतौर पर जावास्क्रिप्ट पक्ष पर नियंत्रित होता है। – serg

0

सत्र थ्रेड सुरक्षित नहीं है और न ही सेट विधियों को थ्रेड सुरक्षित होने की गारंटी है। सामान्य रूप से एक सर्वलेट कंटेनर में आपको एक बहु थ्रेडेड वातावरण में होना चाहिए और कोई भी टूलिंग सुरक्षित नहीं है।

यह आपके द्वारा सत्र में संग्रहीत वस्तुओं के लिए भी जाता है। सत्र स्वयं संग्रहित ऑब्जेक्ट में हेरफेर नहीं करेगा लेकिन आप ऑब्जेक्ट को विभिन्न थ्रेड में पुनर्प्राप्त कर सकते हैं और इसे कुशल बनाने का प्रयास कर सकते हैं। दौड़ की स्थिति संभव है या नहीं, यह देखने के लिए कि आप अपने कोड की जांच कर रहे हैं।

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

61

सर्वलेट 2.5 कल्पना:

एकाधिक सर्वलेट्स अनुरोध निष्पादित धागे एक ही समय में एक ही सत्र वस्तु को सक्रिय पहुँच हो सकती है। कंटेनर को यह सुनिश्चित करना चाहिए कि आंतरिक डेटा सत्र का प्रतिनिधित्व करने वाले संरचना विशेषताएँ थ्रेडसेफ तरीके से प्रदर्शित की जाती हैं। डेवलपर थ्रेडसेफ की विशेषता ऑब्जेक्ट्स तक पहुंच की ज़िम्मेदारी है।यह HttpSession ऑब्जेक्ट के अंदर एक्सेस से के अवसर को समाप्त करने के लिए संग्रह को दूषित होने के कारण विशेषता संग्रह की रक्षा करेगा।

यह सुरक्षित है:

// guaranteed by the spec to be safe 
request.getSession().setAttribute("foo", 1); 

यह नहीं सुरक्षित है:

HttpSession session = request.getSession(); 
Integer n = (Integer) session.getAttribute("foo"); 
// not thread safe 
// another thread might be have got stale value between get and set 
session.setAttribute("foo", (n == null) ? 1 : n + 1); 

यह वह जगह है नहीं सुरक्षित होने की गारंटी:

// no guarantee that same instance will be returned, 
// nor that session will lock on "this" 
HttpSession session = request.getSession(); 
synchronized (session) { 
    Integer n = (Integer) session.getAttribute("foo"); 
    session.setAttribute("foo", (n == null) ? 1 : n + 1); 
} 

मैंने इस अंतिम दृष्टिकोण की वकालत की है (जे 2 ईई किताबों सहित), लेकिन यह सर्वलेट विनिर्देशन द्वारा काम करने की गारंटी नहीं है। आप use the session ID to create a mutex कर सकते हैं, लेकिन एक बेहतर दृष्टिकोण होना चाहिए।

+0

यह समझने की कोशिश कर रहा है कि "कंटेनर को यह सुनिश्चित करना चाहिए कि सत्र गुणों का प्रतिनिधित्व करने वाले आंतरिक डेटा संरचनाओं में हेरफेर एक थ्रेडसेफ तरीके से किया जाता है"। इसका मतलब यह नहीं है कि 'टॉमकैट' जैसे कंटेनर को यह सुनिश्चित करना है कि GetAttribute और setAttribute विधियां थ्रेड सुरक्षित हैं? साथ ही, आखिरी दृष्टिकोण काम करने की गारंटी क्यों नहीं है? – letronje

+0

@letronje - इसका मतलब यह है कि व्यक्तिगत कॉल प्राप्त करने के लिए एट्रिब्यूट/सेट एट्रिब्यूट थ्रेडसेफ होना चाहिए, लेकिन सर्वलेट के लिए कोई लेनदेन गारंटी नहीं है। इसलिए, उसी सत्र के समवर्ती उपयोग के परिणामस्वरूप असंगत स्थिति हो सकती है जब तक कि सर्वलेट डेवलपर इसके खिलाफ सुरक्षा न करे। – McDowell

+1

@letronje - अंतिम दृष्टिकोण की आवश्यकता है कि सत्र 'इस' पर सिंक्रनाइज़ हो। यही है, 'सार्वजनिक सिंक्रनाइज़ेड शून्य सेट एट्रिब्यूट ...' या '... सेट एट्रिब्यूट (स्ट्रिंग एस, ऑब्जेक्ट ओ) {सिंक्रनाइज़ (यह) ... जैसे हस्ताक्षर है। कल्पना के लिए इसकी आवश्यकता नहीं है। कुछ सर्वलेट कंटेनर ऐसा करते हैं, लेकिन कोई गारंटी नहीं है - कैसे कंटेनर आंतरिक स्थिति की रक्षा करता है एक कार्यान्वयन विस्तार है। – McDowell

1

वे नहीं हैं, लेकिन अधिकांश बार, आपके ग्राहक केवल उन्हें एक ही थ्रेड के साथ एक्सेस करेंगे।

विभिन्न ग्राहकों के पास अलग-अलग धागे होंगे और प्रत्येक के पास अपना स्वयं का सत्र होगा।

एडी बताते हैं, एक स्थिति जहां आप एक ही सत्र तक पहुंचने वाले दो धागे का सामना कर सकते हैं, दो AJAX कॉल उसी सत्र विशेषता को संशोधित करने का प्रयास कर रहे हैं। अन्यथा आपको कोई समस्या नहीं होगी।

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