जावा में बहु-सूत्रित वातावरण में स्थैतिक विधि व्यवहार


114

एक साधारण बेवकूफ सवाल है जो मुझे परेशान करता है और मेरे दिमाग में कई तर्क देता है। मैं नीचे दिए गए प्रश्नों के बारे में सभी संदेहों को दूर करना चाहता हूं।

class Clstest{

    public static String testStaticMethod(String inFileStr) {

        // section 0

        // section 1

        // do something with inFileStr

        // section 2

        // section 3

        return inFileStr;

    }

}

मान लें कि पाँच धागे हैं प्रत्येक एक Clstest.testStaticMethod("arg-n")ही समय में एक कॉल निष्पादित कर रहे हैं ।

थ्रेड 1 कॉल Clstest.testStaticMethod("arg-1")

जब थ्रेड 1 अनुभाग 1 में होता है, तो थ्रेड 2 कॉल करता है Clstest.testStaticMethod("arg-2")

फिर थ्रेड 1 का क्या होगा? क्या यह सोने की अवस्था में जाएगा?

जब थ्रेड 1 को मौका मिला तो क्या यह खंड 1 से निष्पादन को फिर से शुरू करेगा जहां इसे रोक दिया गया था?

यह कैसे होता है जब एक Clstest.testStaticMethodऔर एक ही Clstest.testStaticMethodसभी पांच धागे के बीच साझा किया जाता है?

क्या inFileStrकई थ्रेड द्वारा भेजे गए इंटरचेंज को इंटरचेंज करने की कोई संभावना है ?


आप किस भाषा को लक्षित कर रहे हैं?
50मेगामैन

3
@ ओमेगामैन: यह जावा है
namalfernandolk

जवाबों:


192

हंस पैसेंट का जवाब अच्छा है। लेकिन मुझे लगा कि मैं किसी ऐसे व्यक्ति के लिए थोड़ा और सरल स्तर पर कोशिश करूंगा और समझाऊंगा जो जावा के लिए नया है और जावा के लिए नया है। यहाँ जाता हैं..

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

जब कोई थ्रेड एक नई विधि को चलाना शुरू करता है तो यह उस विधि में अपने स्टैक पर तर्कों और स्थानीय चर को बचाता है। इनमें से कुछ मान ढेर पर स्थित वस्तुओं के संकेत हो सकते हैं। यदि दो धागे एक ही विधि पर चल रहे हैं, तो वे दोनों अपने कोड पॉइंटर्स को उस पद्धति पर इंगित करेंगे और उनके ढेर पर उनके तर्क और स्थानीय चर की अपनी प्रतियां होंगी। वे केवल एक दूसरे के साथ हस्तक्षेप करेंगे यदि उनके ढेर पर चीजें ढेर पर समान वस्तुओं को इंगित करती हैं। जिस स्थिति में सभी प्रकार की चीजें हो सकती हैं। लेकिन जैसा कि हंस बताते हैं, स्ट्रिंग्स अपरिवर्तनीय हैं (बदला नहीं जा सकता) इसलिए हम सुरक्षित हैं यदि यह एकमात्र ऐसी वस्तु है जिसे "साझा" किया जा रहा है।

इतने सारे धागे एक ही विधि से चल सकते हैं। वे एक ही समय में नहीं चल सकते हैं - यह निर्भर करता है कि आपके मशीन पर कितने कोर हैं जैसे कि जेवीएम जावा थ्रेड्स से ओएस थ्रेड्स पर मैप करता है, जो हार्डवेयर थ्रेड्स पर निर्धारित होते हैं। इसलिए आपके पास जटिल सिंक्रनाइज़ेशन तंत्र का उपयोग किए बिना इन थ्रेड्स को इंटरलेव करने के तरीके पर थोड़ा नियंत्रण है।

ध्यान दें कि सोना एक ऐसी चीज़ है जो खुद एक धागा है।


3
तो, मल्टी-कोर प्रोसेसर वातावरण में एक ही समय में एक ही कोड को चलाने वाले कई धागे हो सकते हैं? और एकल प्रोसेसर वातावरण में एक निश्चित समय पर केवल एक धागा चलता है। (कई थ्रेड्स उनके बीच के समय को साझा करते हैं।) इसलिए, जब थ्रेड शेड्यूलर करंट एक्सुलेटिंग थ्रेड (ए) से थ्रेड (बी) तक का मौका देता है, तो थ्रेड (ए) को फिर से कैसे शुरू किया जाता है, जहां से इसे रोका गया था? मेरा मतलब है कि यह फिर से शुरू बिंदु को कैसे जानता है? क्या ऐसा इसलिए है क्योंकि "प्रत्येक थ्रेड में कोड में एक पॉइंटर भी होता है जो उस कोड के बिट की ओर इशारा करता है जो वे वर्तमान में चला रहे हैं?" जैसा कि आपने कहा?
15 जनवरी को namalfernandolk

6
तुम्हें यह मिल गया है। बस कुछ बिंदुओं को स्पष्ट करने के लिए - सबसे पहले, धागे कैसे निर्धारित किए जाते हैं यह जावा के नियंत्रण से बाहर है। मैं यहाँ Sun's Hotspot JVM की बात कर रहा हूँ। JVM एक OS थ्रेड के लिए एक जावा थ्रेड मैप करता है और OS तय करता है कि कौन से थ्रेड को चलाना है। जैसा कि आप कहते हैं, एक ही कोर मशीन पर OS केवल एक बार ही चल सकता है, लेकिन एक मल्टीकोर मशीन में यह एक बार में एक से अधिक चला सकता है। दूसरे, एक थ्रेड वास्तव में पता नहीं है जब यह रोक दिया जाता है, इसकी एकमात्र जानकारी यह है कि यह प्रोग्राम पॉइंटर (कोड में सूचक) और स्टैक है, जो सहेजे जाते हैं और ठीक उसी तरह बहाल होते हैं जैसे वे थे।
सेलेग

तो, इंटर-थ्रेड इंटरफेरेंस तब होता है जब थ्रेड्स अपने स्थानीय दायरे से बाहर चर का उपयोग कर रहे हैं और, उदाहरण के लिए, एक धागा दूसरे थ्रेड को खींचने से पहले वेरिएबल के वैल्यू को वेरिएबल (या वेरिएबल को पॉइंटर) अपने स्टैक पर अपडेट करता है? क्या यह एक सही समझ है?
hariszhr

2
थोड़ा और सटीक होने के लिए ... हस्तक्षेप केवल हो सकता है और हो सकता है लेकिन जरूरी नहीं होगा ... जब थ्रेड्स ढेर (गैर-स्थानीय) पर चीजें साझा करते हैं। कुछ अलग तरीके हैं हस्तक्षेप हो सकता है जो कोड के विभिन्न भागों के बीच निर्भरता पर निर्भर करता है। मुझे आपके उदाहरण पर यकीन नहीं है क्योंकि कुछ विवरण गायब हैं। शायद आप एक संभावित मुद्दे का उल्लेख कर रहे हैं जहां थ्रेड ए और बी दोनों एक साझा मूल्य को पढ़ते हैं और फिर दोनों इसे पढ़े गए मूल्य के आधार पर अपडेट करते हैं। यह एक डेटा रेस है।
सेलेग

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

67

क्या यह सोने की अवस्था में जाएगा?

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

वहाँ कई धागे द्वारा भेजे गए inFileStr इंटरचेंज करने की कोई संभावना है?

ऐसी कोई संभावना नहीं है, थ्रेड्स का अपना स्टैक होता है इसलिए किसी भी विधि तर्क और स्थानीय चर प्रत्येक थ्रेड के लिए अद्वितीय होंगे। इसके अलावा स्ट्रिंग का उपयोग यह गारंटी देता है कि ये धागे एक दूसरे के साथ हस्तक्षेप नहीं कर सकते हैं क्योंकि तार अपरिवर्तनीय हैं।

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


3
उफ़, [जावा] टैग कभी नहीं देखा। पर्याप्त नजदीक।
हंस पैसेंट

जब पोस्ट किया गया तो मैं जोड़ना भूल गया। मेरी गलती। :)। किसी भी तरह से जवाब के लिए धन्यवाद। यह बहुत मददगार था।
नमलफरनडालोक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.