यदि वे स्थिर वर्ग चर को संशोधित नहीं करते हैं तो क्या गैर-सिंक्रनाइज़ स्थिर स्टेटस थ्रेड सुरक्षित हैं?


145

मैं सोच रहा था कि क्या आपके पास एक स्थिर विधि है जो सिंक्रनाइज़ नहीं है , लेकिन किसी स्थिर चर को संशोधित नहीं करता है क्या यह थ्रेड-सुरक्षित है? क्या होगा अगर विधि इसके अंदर स्थानीय चर बनाता है? उदाहरण के लिए, निम्न कोड थ्रेड सुरक्षित है?

public static String[] makeStringArray( String a, String b ){
    return new String[]{ a, b };
}

इसलिए अगर मेरे पास दो सूत्र हैं, जो लगातार और समवर्ती रूप से ths पद्धति को कहते हैं, एक कुत्तों के साथ (जैसे "महान डेन" और "बुल डॉग") और दूसरा बिल्लियों के साथ (जैसे "फ़ारसी" और "सियामीज़") क्या मैं कभी बिल्लियों और कुत्तों के साथ रहूंगा। उसी सरणी में? या क्या बिल्लियाँ और कुत्ते एक ही समय में विधि के एक ही आह्वान के अंदर नहीं होंगे?


इस मुद्दे पर एक और सूत्र: stackoverflow.com/questions/8015797/…
嘉 道

2
यह एक अलग सवाल है, यह है कि क्या स्टैटिक मेथड इनवोकेशन थ्रेड सेफ है, न कि एरेज़।
स्लेज

जवाबों:


212

यह विधि 100% धागा सुरक्षित है, यह तब भी होगा जब यह नहीं था static। थ्रेड-सुरक्षा के साथ समस्या तब उत्पन्न होती है जब आपको थ्रेड्स के बीच डेटा साझा करने की आवश्यकता होती है - आपको परमाणुता, दृश्यता आदि का ध्यान रखना चाहिए।

यह विधि केवल मापदंडों पर काम करती है , जो ढेर पर रहती है और ढेर पर अपरिवर्तनीय वस्तुओं का संदर्भ देती है। स्टैक स्वाभाविक रूप से थ्रेड के लिए स्थानीय है , इसलिए डेटा का कोई भी बंटवारा कभी नहीं होता है।

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


4
सही उत्तर। विधि स्तर चर प्रत्येक थ्रेड निष्पादन स्टैक में दोहराया जाता है।
सिड

तकनीकी रूप से विधि को इनलाइन किया जाना है और पैरामीटर सीपीयू रजिस्टर होंगे। फिर भी जवाब सही है
bestsss

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

1
जैसा कि @TomaszNurkiewicz ने उल्लेख किया है, यदि हम एक उत्परिवर्तनीय वस्तु संदर्भ पास करते हैं, तो हम दौड़ की स्थिति में आ सकते हैं। क्या यह सही है भले ही विधि किसी भी तरह से वस्तु को न बदले? मेरा मतलब है, क्या इसे अभी भी एक दौड़ की स्थिति के रूप में वर्गीकृत किया जाएगा क्योंकि वस्तु परस्पर थी? और क्या होगा अगर हम मापदंडों में अंतिम कीवर्ड जोड़ते हैं?
रफय

क्या होगा यदि मैं विधि में कक्षा ऑब्जेक्ट पास करूं? ढेर या ढेर में परिवर्तनशील होगा?
grep

28

एक विधि केवल थ्रेड-असुरक्षित हो सकती है जब यह कुछ साझा स्थिति को बदलती है। यह स्थिर है या नहीं अप्रासंगिक है।


3
@Konrad_Garus यहां सवाल यह था कि स्थानीय चर साझा राज्य का गठन करते हैं या नहीं, या एक स्थिर विधि के लिए स्टैक प्रति थ्रेड या साझा किया गया था।
स्लेज

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

12

फ़ंक्शन पूरी तरह से थ्रेड सुरक्षित है।

यदि आप इसके बारे में सोचते हैं ... मान लें कि अगर यह अलग होता तो क्या होता। हर सामान्य फ़ंक्शन को समस्‍या होने पर थ्रेडिंग समस्‍या होती है, इसलिए JDK में सभी API फ़ंक्शन को समन्‍वयित करना होगा, क्‍योंकि वे संभावित रूप से कई थ्रेड द्वारा कहे जा सकते हैं। और जब से अधिकांश बार ऐप कुछ एपीआई का उपयोग कर रहा है, मल्टीथ्रेडेड एप्लिकेशन प्रभावी रूप से असंभव होगा।

इस बारे में सोचना बहुत हास्यास्पद है, इसलिए सिर्फ आपके लिए: अगर समस्याएँ हो सकती हैं तो इसका एक स्पष्ट कारण है कि तरीके स्पष्ट नहीं हैं। हमेशा यह सोचने की कोशिश करें कि अगर मेरे कार्य में कई थ्रेड्स थे, और क्या होगा यदि आपके पास एक कदम-डिबगर था और एक कदम आगे बढ़ने के बाद पहले ... फिर दूसरा धागा ... शायद दूसरा फिर से ... क्या समस्याएं होंगी? यदि आप एक पाते हैं, तो इसका धागा सुरक्षित नहीं है।

कृपया यह भी अवगत रहें, कि Java 1.5 कलेक्शन क्लासेस में से अधिकांश थ्रेडसेफ़ नहीं हैं, सिवाय उन लोगों को छोड़कर, जहाँ कहा गया है, जैसे समवर्ती हाशप।

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

इस विस्तृत जवाब के लिए क्षमा करें।


2
"यदि आप इसके बारे में सोचते हैं ... मान लें कि यह अलग होता तो क्या होता। हर सामान्य फ़ंक्शन में समस्याएँ होती अगर सिंक्रनाइज़ नहीं होतीं, इसलिए JDK में सभी API फ़ंक्शंस को सिंक्रनाइज़ करना पड़ता, क्योंकि वे संभावित रूप से एकाधिक कह सकते हैं धागे। " अच्छी बात!
स्लेज

1

staticथ्रेड के बीच साझा किए गए स्थिर डेटा को संशोधित करने के लिए सिंक्रनाइज़ किए गए स्थिर तरीकों के साथ कीवर्ड का उपयोग करें । staticकीवर्ड के साथ बनाए गए सभी थ्रेड विधि के एकल संस्करण के लिए प्रतिस्पर्धा करेंगे।

volatileसिंक्रनाइज़ उदाहरण विधियों के साथ कीवर्ड का उपयोग करें गारंटी देगा कि प्रत्येक थ्रेड में साझा डेटा की अपनी प्रतिलिपि है और थ्रेड के बीच कोई रीड / राइट लीक नहीं होगा।


0

स्ट्रिंग के अपरिवर्तनीय होने के कारण ऊपर धागा-सुरक्षित परिदृश्य का एक और कारण है। इसके बजाय अगर उत्परिवर्तित वस्तुओं का उपयोग किया जाता है (MakeMutableArray .. कहते हैं) तो निश्चित रूप से थ्रेड-सेफ्टी टूट जाएगी।


सवाल यह था कि क्या स्टैटिक मेथड कॉल कभी दूसरे थ्रेड से एक ही विधि के लिए किसी अन्य कॉल के तर्कों को देखेगी। उत्तर है एक ज़बर्दस्त ना!"। यह, मैं जानता था लेकिन संदिग्ध सहकर्मियों को साबित करने में सक्षम होना चाहता था।
स्लेज

इस प्रतिक्रिया को वोट-डाउन क्यों किया गया? बिंदु, अन्य उत्तरों द्वारा योगदान नहीं किया गया है, यह है कि उत्परिवर्तन इन-बाउंड या आउट-बाउंड हो सकता है। यदि आप एक उत्परिवर्ती लौटाते हैं, तो आप थ्रेडसेफ़ नहीं हैं। टिप्पणी के रूप में सवाल के रूप में इस सवाल को संकीर्ण रूप से नहीं बताया गया है; कोड नमूना के बाद विस्तारित प्रश्न कोड में व्यक्त किया जा सकता है, शायद एक इकाई परीक्षण के रूप में। लेकिन मैं सहकर्मियों को समझाने की सहानुभूति रखता हूं। "वे मुझ पर, या मेरे परीक्षण कोड, या जोश बलोच पर विश्वास नहीं करते हैं, लेकिन शायद वे SO पर उत्तर स्वीकार करेंगे।"
सोम-संवत
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.