2011-10-30 11 views
6

मेरे जावा ऐप्लिकेशन इंजन परियोजना Memcache के निम्न उपयोगों के लिए छोड़कर अनुरोधों के बीच किसी भी राज्य नहीं रखता:चेकलिस्ट

  • objectify डेटासंग्रह
  • मैं के रूप में मेम्कैश का उपयोग हो जाता है कैश करने के लिए मेम्कैश का उपयोग करता है एकाधिक अनुरोधों के बाद क्लीनअप कार्यों को बैच करने का एक तरीका (जैसे if (the memcache doesn't think a cleanup task is already running) schedule another cleanup task)।

    • वर्तमान प्रमाणीकृत उपयोगकर्ता एक static ThreadLocal<User> वस्तु में रखा जाता है:

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

  • मेरे पास एक कक्षा है जो सभी डेटा मैनिपुलेशन को संभालती है, और एक उदाहरण को static DataCoordinator ऑब्जेक्ट में वैश्विक चर के प्रकार के रूप में रखा जाता है।

मुझे अपना कोड थ्रेड-सुरक्षित बनाने के लिए क्या देखने की आवश्यकता है? क्या मुझे synchronized कीवर्ड को मेरे DataCoordinator कार्यान्वयन में प्रत्येक विधि घोषणा में फेंकने की आवश्यकता है, क्योंकि एकाधिक धागे इसे एक्सेस कर सकते हैं? क्या यह सच है कि ThreadLocal<User> ऑब्जेक्ट हमेशा प्रत्येक थ्रेड के लिए User ऑब्जेक्ट अलग करेगा, ताकि प्रत्येक अनुरोध को अलग से प्रमाणित किया जा सके?

मैं थ्रेड-सुरक्षित सोच के लिए कुल नौसिखिया हूं। मुझे क्या पढ़ना चाहिए?

किसी भी मदद के लिए धन्यवाद, और विशिष्टता की कमी के लिए खेद है।

+0

आप किसी भी singlton कक्षाएं, जहां आप हमेशा एक .getInstance के माध्यम से एक ही उदाहरण के लिए एक संदर्भ प्राप्त है()? यदि ऐसा है, तो एक ही वीएम/इंस्टेंस के अंदर विभिन्न धागे में निष्पादित कई समांतर अनुरोधों को उसी ऑब्जेक्ट का संदर्भ मिल रहा है .... और उसके बाद कक्षा का उपयोग या आवृत्ति चर के संशोधन में। –

उत्तर

7

सबसे पहले आपको पता होना चाहिए कि ऐप इंजन आपके सर्वर को कई सर्वरों पर दोहरा सकता है। इसका मतलब है कि आपके स्थैतिक चर केवल एक सर्वर पर अद्वितीय होंगे। इस प्रकार आपका DataCoordinator केवल एक सर्वर पर डेटा पहुंच समन्वयित करेगा। इसलिए यदि आपको अपने ऐप को चलाने वाले सभी सर्वरों के लिए सामान्य डेटा की आवश्यकता है तो आपको हमेशा उस डेटा स्टोर का उपयोग करना चाहिए (या कुछ मामलों में जीएई HTTP सत्र तंत्र)।

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

आपके ThreadLocal के बारे में ऑथ टोकन स्टोर करने के लिए उपयोग किया जाता है: आप ऐसा कर सकते हैं (उदाहरण के लिए मैं जीडब्ल्यूटी अनुरोध कारखाने के अनुरोधों के लिए जीई में उपयोगकर्ता प्रमाणीकरण के लिए ऐसा करता हूं) और हां, प्रत्येक थ्रेड के पास आपके स्वयं के चर मूल्य होंगे जब तक आप सेट करते हैं यह उस धागे के लिए। इसका अर्थ यह सुनिश्चित करना सबसे अच्छा है कि चर प्रत्येक थ्रेड के लिए सेट किया गया है और try - finally का उपयोग करने के लिए सलाह दी जाती है- इसे सेट करने के बाद अंततः उपयोग करने के बाद प्रमाणीकरण डेटा को हटा दें। क्यूं कर? सबसे खराब चीज जो हो सकती है अन्यथा यह होगा कि उपयोगकर्ता बी के अनुरोध से संबंधित एक धागा अभी भी उपयोगकर्ता ए का एक प्रतीक है। ऐसा इसलिए है क्योंकि एप्लिकेशन सर्वर में उपयोग किए गए थ्रेड आमतौर पर सफाई और पुनर्निर्मित करने के बजाय अनुरोधों के बीच पूल किए जाते हैं।

मैं memcache के बारे में कुछ भी नहीं कह सकता क्योंकि मैंने इसका उपयोग नहीं किया है।

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

शायद http://download.oracle.com/javase/tutorial/essential/concurrency/ इसमें पढ़ने के लिए एक अच्छा प्रारंभिक बिंदु है।

+0

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

3

यदि आपके पास सिंगलटन कक्षाएं हैं, तो आपके कोड प्रति वीएम/इंस्टेंस द्वारा बनाए गए केवल एक उदाहरण का उपयोग/उपयोग किया जाएगा।

इस सिंगलटन का संदर्भ से दिलवाया जा सकता है:
- दो अनुक्रमिक अनुरोध एक और है कि एक ही उदाहरण से सेवा कर रहे हैं के बाद से एक बना दिया (कितनी देर तक वे चारों ओर रहने के लिए, या उसमें आरक्षित उदाहरण चल रहा है तो अपनी सेटिंग्स पर निर्भर करता है)
- एक ही उदाहरण पर अलग-अलग धागे में चलने वाले दो समांतर अनुरोध यदि आपके पास थ्रेडसेफ सत्य पर सेट है।

मैंने अपने आप को यह पुष्टि करने के लिए कोड लिखा है और परीक्षण किया है, और तैनात और परीक्षण किया है। यदि एक अनुरोध में कोड एकल सदस्य चर के संशोधित करने के लिए सिंगलटन का उपयोग करता है, तो इसे समानांतर में चल रहे अन्य अनुरोध के लिए संशोधित किया जाता है।

सभी लॉजिकल वास्तव में, एक बार जब आप वीएम के जीवनकाल को समझते हैं और आने वाले अनुरोधों को पूरा करने के लिए कितने धागे (केवल 1, या कई) का उपयोग किया जाता है।

इसके अलावा, सिस्टम चर को एक अनुरोध में कोड में संशोधित किया जा सकता है और दूसरे में पढ़ा जा सकता है ... दूसरा तरीका दो समांतर अनुरोध/धागे बातचीत कर सकते हैं।

GAE/जम्मू यहाँ में बहु सूत्रण पर अपने ब्लॉग पोस्ट में इस बारे में अधिक जानकारी देखें:
http://devcon5.blogspot.com/2012/09/threadsafe-in-appengine-gaej.html

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