जावा मेमोरी मॉडल से पैर कहां हैं

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

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

लेकिन हर कोई पहले से ही महसूस कर चुका है, क्योंकि किसी तरह आपको इसके साथ रहना होगा। और जावा प्रोग्रामर भी अच्छी तरह से रहते हैं। क्योंकि जावा में एक मेमोरी मॉडल है - जावा मेमोरी मॉडल (जेएमएम), जो सही बहु-थ्रेडेड कोड लिखने के लिए काफी सरल नियम प्रदान करता है।

और ये नियम अधिकांश कार्यक्रमों के लिए पर्याप्त हैं। यदि आप उन्हें नहीं जानते हैं, लेकिन जावा में बहु-थ्रेडेड प्रोग्राम लिखना या लिखना चाहते हैं, तो जितनी जल्दी हो सके अपने आप को उनके साथ परिचित करना सबसे अच्छा है। और यदि आप जानते हैं, लेकिन आपके पास पर्याप्त संदर्भ नहीं है या यह जानना दिलचस्प है कि जेएमएम के पैर कहाँ से बढ़ते हैं, तो यह लेख आपकी मदद कर सकता है।

और अमूर्तता का पीछा करते हुए


मेरी राय में, एक पाई, या, अधिक उपयुक्त, एक हिमशैल है। JMM हिमखंड का सिरा है। हिमखंड अपने आप में पानी के नीचे बहु-सूत्रीय प्रोग्रामिंग का एक सिद्धांत है। हिमखंड के नीचे नर्क है।



एक हिमशैल एक अमूर्त है, अगर यह लीक होता है, तो हम निश्चित रूप से नर्क देखेंगे। हालाँकि वहाँ बहुत सी दिलचस्प चीजें हो रही हैं, समीक्षा लेख में हमें यह नहीं मिला।

लेख में, मैं निम्नलिखित विषयों में अधिक रुचि रखता हूं:

  • सिद्धांत और शब्दावली
  • JMM में परिलक्षित मल्टीथ्रेड प्रोग्रामिंग का सिद्धांत कैसे है
  • प्रतिस्पर्धी प्रोग्रामिंग मॉडल

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

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

प्रतियोगिता और संगति


सबसे पहले, हम शब्दावली को देखते हैं। दुर्भाग्य से, शब्दावली में कोई आम सहमति नहीं है - विभिन्न सामग्रियों का अध्ययन करते समय, आप प्रतियोगिता और संगति की विभिन्न परिभाषाओं में आ सकते हैं।

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

रोमन एलिसारोव, एक रिपोर्ट में, चिकित्सकों के लिए समानांतर प्रोग्रामिंग का सिद्धांत बताता है कि कभी-कभी ये अवधारणाएं मिश्रित होती हैं। समानांतर प्रोग्रामिंग कभी-कभी एक सामान्य अवधारणा के रूप में प्रतिष्ठित होती है जिसे प्रतिस्पर्धी और वितरित में विभाजित किया जाता है।

मुझे ऐसा लगता है कि झामुमो के संदर्भ में आपको अभी भी प्रतिस्पर्धा और समानता को अलग करने की आवश्यकता है, या यहां तक ​​कि यह भी समझें कि दो अलग-अलग प्रतिमान हैं, चाहे वे कैसे भी कहे जाएं।

अक्सर रॉब पाइक द्वारा उद्धृत, जो अवधारणाओं के बीच अंतर करता है:

  • प्रतियोगिता एक साथ कई समस्याओं को हल करने का एक तरीका है
  • कंसीडर एक कार्य के विभिन्न भागों को करने का एक तरीका है।

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

सबसे अधिक संभावना है, अगर हम एक प्रतिस्पर्धी और समानांतर कार्यक्रम की मुख्य विशेषताओं को उजागर करते हैं, तो मुद्दे की अधिक समझ दिखाई देगी। बहुत सारे संकेत हैं, सबसे महत्वपूर्ण पर विचार करें।

प्रतियोगिता के संकेत।

  • कई नियंत्रण प्रवाह की उपस्थिति (उदाहरण के लिए, थ्रेड इन जावा, कोटलिन में कोटलिन), यदि केवल एक नियंत्रण प्रवाह है, तो कोई प्रतिस्पर्धी निष्पादन नहीं हो सकता है
  • गैर-निर्धारक परिणाम। परिणाम यादृच्छिक घटनाओं, कार्यान्वयन, और सिंक्रनाइज़ेशन कैसे किया गया था पर निर्भर करता है। यहां तक ​​कि अगर प्रत्येक धारा पूरी तरह से निर्धारक है, तो अंतिम परिणाम गैर-निर्धारक होगा

एक समानांतर कार्यक्रम में सुविधाओं का एक अलग सेट होगा।

  • वैकल्पिक में कई नियंत्रण प्रवाह होते हैं
  • यह एक नियतात्मक परिणाम को जन्म दे सकता है, उदाहरण के लिए, सरणी के प्रत्येक तत्व को एक संख्या से गुणा करने का परिणाम नहीं बदलेगा यदि आप इसे समानांतर में भागों में गुणा करते हैं

विचित्र रूप से पर्याप्त, एकल नियंत्रण प्रवाह पर समानांतर निष्पादन संभव है, और यहां तक ​​कि एकल-कोर वास्तुकला पर भी। तथ्य यह है कि कार्यों के स्तर पर समानता (या नियंत्रण प्रवाह) जिससे हम आदी हैं, समानांतर में गणना करने का एकमात्र तरीका नहीं है।

इस स्तर पर सम्‍मिलन संभव है

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

निर्देश स्तर पर Concurrency कोड अनुकूलन के साथ आने वाले अनुकूलन का एक उदाहरण है जो प्रोग्रामर से छिपा हुआ है।

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

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

शब्दावली बहुत अस्थिर है, रोमन एलिसारोव की एक प्रस्तुति के साथ "चिकित्सकों के लिए समानांतर प्रोग्रामिंग का सिद्धांत" कहा जाता है, हालांकि प्रतिस्पर्धी प्रोग्रामिंग के बारे में अधिक है, अगर आप ऊपर से चिपके रहते हैं।

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

एक सामान्य स्थिति वाले मॉडल: "ऑपरेशन का रोटेशन" और "पहले हुआ"


अपने लेख में, मौरिस हर्लिची (द आर्ट ऑफ मल्टीप्रोसेसर प्रोग्रामिंग के लेखक) लिखते हैं कि एक प्रतिस्पर्धी प्रणाली में अनुक्रमिक प्रक्रियाओं का एक संग्रह होता है (सैद्धांतिक कार्यों में इसका मतलब एक धागे के समान होता है) जो कि साझा स्मृति के माध्यम से संवाद करते हैं।

सामान्य राज्य मॉडल में संदेश के साथ संगणनाएं शामिल हैं, जहां साझा राज्य एक संदेश कतार है और साझा स्मृति के साथ संगणना है, जहां आम राज्य स्मृति में संरचनाएं हैं।

गणना के प्रत्येक अनुकरण किया जा सकता है।

मॉडल एक परिमित राज्य मशीन पर आधारित है। मॉडल विशेष रूप से साझा स्थिति पर केंद्रित है और प्रत्येक प्रवाह के स्थानीय डेटा को पूरी तरह से अनदेखा किया गया है। एक साझा राज्य पर प्रवाह की प्रत्येक क्रिया एक नए राज्य में संक्रमण का एक कार्य है।

उदाहरण के लिए, यदि 4 थ्रेड्स एक साझा चर के लिए डेटा लिखते हैं, तो एक नए राज्य में संक्रमण के लिए 4 कार्य होंगे। इन कार्यों में से कौन सा लागू किया जाएगा प्रणाली में घटनाओं के कालक्रम पर निर्भर करता है।

संदेश-पासिंग गणना एक समान तरीके से की जाती है, केवल संदेश भेजने या प्राप्त करने पर राज्य और संक्रमण कार्य निर्भर करते हैं।

यदि मॉडल आपको जटिल लग रहा था, तो उदाहरण में हम इसे ठीक कर देंगे। यह वास्तव में बहुत सरल और सहज है। इतना अधिक कि इस मॉडल के अस्तित्व के बारे में जाने बिना, अधिकांश लोग अभी भी कार्यक्रम का विश्लेषण करेंगे जैसा कि मॉडल का सुझाव है।

इस तरह के मॉडल को संचालन के विकल्प के माध्यम से एक प्रदर्शन मॉडल कहा जाता है (रोमन एलिसारोव द्वारा एक रिपोर्ट में नाम सुना गया था)।

सहजता और स्वाभाविकता में आप सुरक्षित रूप से मॉडल के फायदे लिख सकते हैं। आप कीवर्ड अनुक्रमिकता और लेसली लामपोर्ट के काम के साथ विडाल में जा सकते हैं।

हालांकि, इस मॉडल के बारे में एक महत्वपूर्ण स्पष्टीकरण है। मॉडल की सीमा है कि एक साझा स्थिति पर सभी क्रियाएं तात्कालिक होनी चाहिए और एक ही समय में, क्रियाएं एक साथ नहीं हो सकती हैं। वे कहते हैं कि इस तरह की प्रणाली में एक रैखिक आदेश है - सिस्टम में सभी कार्यों का आदेश दिया जाता है।

व्यवहार में, ऐसा नहीं होता है। ऑपरेशन तुरंत नहीं होता है, लेकिन एक अंतराल में किया जाता है, मल्टी-कोर सिस्टम पर, ये अंतराल अंतर कर सकते हैं। बेशक, इसका मतलब यह नहीं है कि मॉडल व्यवहार में बेकार है, आपको बस इसके उपयोग के लिए कुछ शर्तों को बनाने की आवश्यकता है।

इस बीच, एक और मॉडल पर विचार करें - "पहले हुआ था," जो राज्य पर केंद्रित नहीं है, लेकिन निष्पादन (इतिहास) और उनके संबंधों के दौरान मेमोरी कोशिकाओं को पढ़ने और लिखने के सेट पर है।

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

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

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

और हम वास्तव में रिकॉर्डिंग का परिणाम नहीं देख सकते हैं, अर्थात्। एक वेरिएबल में जिसका मान 0 पी स्ट्रीम में है , हम 1 लिखते हैं, और स्ट्रीम क्यू में हम इस वेरिएबल को पढ़ते हैं। रिकॉर्डिंग के बाद कितना भी भौतिक समय बीत जाए, फिर भी हम 0 पढ़ सकते हैं।

यह कंप्यूटर कैसे काम करता है और मॉडल यह दर्शाता है।

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

घटनाएँ समानांतर रूप से घटित होती हैं, जैसा कि हमें पता चला है। लेकिन फिर भी, सिस्टम के पास एक आंशिक आदेश है , क्योंकि घटनाओं के विशेष जोड़े हैं जिनके पास एक आदेश है, जिस स्थिति में वे कहते हैं कि इन घटनाओं का संबंध "पहले हुआ" है। यदि आप पहली बार "पहले हुए रिश्ते" के बारे में सुनते हैं, तो शायद इस तथ्य को जानते हुए कि इस तरह की व्यवस्था घटनाओं के संबंध में आपकी बहुत मदद नहीं करेगी।

जावा प्रोग्राम का विश्लेषण करने की कोशिश कर रहा है


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

एक क्लासिक उदाहरण।

private static int x = 0, y = 0; private static int a = 0, b = 0; synchronized (this) { a = 0; b = 0; x = 0; y = 0; } Thread p = new Thread(() -> { a = 1; x = b; }); Thread q = new Thread(() -> { b = 1; y = a; }); p.start(); q.start(); p.join(); q.join(); System.out.println("x=" + x + ", y=" + y); 

हमें इस कार्यक्रम के निष्पादन को अनुकरण करने और सभी संभावित परिणाम प्राप्त करने की आवश्यकता है - चर x और y के मान। कई परिणाम होंगे, जैसा कि हम सिद्धांत से याद करते हैं, ऐसा कार्यक्रम गैर-नियतात्मक है।

हम कैसे मॉडल करेंगे? मैं तुरंत संचालन के इंटरलेविंग मॉडल का उपयोग करना चाहता हूं। लेकिन "पहले हुआ" मॉडल हमें बताता है कि एक थ्रेड में ईवेंट्स दूसरे थ्रेड की घटनाओं के समानांतर हैं। इसलिए, यदि ऑपरेशन के बीच "पहले" नहीं हुआ है, तो यहां वैकल्पिक संचालन का मॉडल उपयुक्त नहीं है।

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

विकल्प क्या हैं?

बाधाओं को अनदेखा करें और इंटरलेविंग का अनुकरण करें। आप यह कोशिश कर सकते हैं, शायद कुछ भी बुरा नहीं होगा।

यह समझने के लिए कि किस प्रकार के परिणाम प्राप्त किए जा सकते हैं, हम बस निष्पादन के सभी संभावित वेरिएंट की गणना करते हैं।

सभी संभावित कार्यक्रम निष्पादन को एक परिमित राज्य मशीन के रूप में दर्शाया जा सकता है।



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

कुल में, 6 अलग-अलग निष्पादन संभव हैं, जिसके परिणामस्वरूप x, y मानों के जोड़े हैं:
(1, 1), (1, 0), (0, 1)



हम कार्यक्रम को चला सकते हैं और परिणामों की जांच कर सकते हैं। जैसा कि एक प्रतिस्पर्धी कार्यक्रम होता है, इसका एक गैर-निर्धारक परिणाम होगा।

प्रतिस्पर्धी कार्यक्रमों के परीक्षण के लिए, विशेष उपकरण ( उपकरण , रिपोर्ट ) का उपयोग करना बेहतर है।

लेकिन आप कार्यक्रम को कई मिलियन बार चलाने की कोशिश कर सकते हैं, या इससे भी बेहतर, एक चक्र लिख सकते हैं जो हमारे लिए ऐसा करेगा।

यदि हम एक-कोर या एकल-प्रोसेसर आर्किटेक्चर पर कोड चलाते हैं, तो हमें उस सेट से परिणाम प्राप्त करना चाहिए जिसकी हम अपेक्षा करते हैं। रोटेशन मॉडल बस ठीक काम करेगा। मल्टी-कोर आर्किटेक्चर पर, उदाहरण के लिए x86, हम परिणाम से आश्चर्यचकित हो सकते हैं - हम परिणाम (0,0) प्राप्त कर सकते हैं, जो हमारे मॉडलिंग के अनुसार नहीं हो सकता है।

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

प्रतिस्पर्धी प्रोग्रामिंग और JMM का सिद्धांत


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

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

झामुमो में विभिन्न आदेश हैं। अलेक्सी शिपिलेव ने अपनी एक रिपोर्ट में नियमों के बारे में बहुत सख्ती से बात की है

वैश्विक समय मॉडल में, एक ही धागे में सभी संचालन क्रम में हैं। उदाहरण के लिए, एक चर को लिखने और पढ़ने की घटनाओं को दो अंतराल के रूप में दर्शाया जा सकता है, फिर मॉडल गारंटी देता है कि ये अंतराल कभी भी एक धारा के ढांचे के भीतर अंतर नहीं करेंगे। JMM में, इस आदेश को प्रोग्राम ऑर्डर ( PO ) कहा जाता है।

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

हमारे उदाहरण में, हमें कुछ ऐसा मिलता है:

P: a = 1 PO x = b - a और रीडिंग b लिखने से PO ऑर्डर होता है
Q: b = 1 PO y = a - to b लिखिए और पढ़िए PO आदेश

मैंने डब्ल्यू (ए, 1) पीओ आर (बी) लिखने के इस रूप की जासूसी की : 0. मुझे वास्तव में उम्मीद है कि किसी ने भी रिपोर्ट के लिए इसका पेटेंट नहीं कराया है। हालांकि, विनिर्देश का एक समान रूप है।

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

आपको याद दिला दूं कि यह हमारे लिए कारगर नहीं था, क्योंकि अलग-अलग विधाओं में लिखने और पढ़ने के चर का संचालन तात्कालिक नहीं होता है (ये ऐसे खंड हैं जो प्रतिच्छेद करते हैं), क्रमशः, जहां संचालन की शुरुआत और अंत होते हैं वहां पार्स करना असंभव है।

यह विचार सरल है - जिस समय हम चर को स्ट्रीम Q में पढ़ते हैं, उसी समय P के स्ट्रीम में इसी वेरिएबल का रिकॉर्ड समाप्त हो सकता है। और कोई फर्क नहीं पड़ता कि ये घटनाएं कितना भौतिक समय साझा करती हैं - एक नैनोसेकंड या कुछ घंटे।

घटनाओं का आदेश देने के लिए, हमें "रिश्ते से पहले हुआ" चाहिए। झामुमो इस रिश्ते को परिभाषित करता है। विनिर्देश एक धागे में आदेश को ठीक करता है:

यदि ऑपरेशन x और y एक ही थ्रेड में हैं और PO x में पहले होता है, और फिर y, तो x y से पहले हुआ।


आगे देखते हुए, हम कह सकते हैं कि हम सभी POs को हैपन्स- बिफोर ( HB ) से बदल सकते हैं:

 P: w(a, 1) HB r(b) Q: w(b, 1) HB r(a) 

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

सिंक्रोनाइज़ेशन ऑर्डर ( SO ) - लिंक सिंक्रोनाइज़ेशन एक्ट्स ( SA ), एसए की पूरी सूची विनिर्देशन में दी गई है, धारा 17.4.2 में। क्रिया। यहाँ उनमें से कुछ हैं:

  • वाष्पशील चर पढ़ना
  • लेखन अस्थिर चर
  • मॉनिटर लॉक
  • मॉनीटर अनलॉक करें

एसओ हमारे लिए दिलचस्प है, क्योंकि इसमें संपत्ति है कि एसओ के आदेश में सभी रीडिंग एसओ में अंतिम प्रविष्टियां देखते हैं। और मैं आपको याद दिलाता हूं, हम केवल इसे प्राप्त कर रहे हैं।

इस जगह पर, मैं वही दोहराऊंगा जो हम कर रहे हैं। हमारे पास एक बहुस्तरीय कार्यक्रम है, हम सभी संभावित निष्पादन को अनुकरण करना चाहते हैं और सभी परिणाम प्राप्त कर सकते हैं जो यह दे सकते हैं। ऐसे मॉडल हैं जो इसे काफी सरलता से करने की अनुमति देते हैं। लेकिन उन्हें आवश्यकता है कि साझा राज्य पर सभी कार्यों का आदेश दिया जाए।

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

एक और सिंक्रोनाइज़-विद ऑर्डर ( एसडब्ल्यू ) पर विचार करें - विशिष्ट अनलॉक / लॉक के लिए एसओ ऑर्डर, अस्थिर जोड़े लिखें / पढ़ें। इससे कोई फर्क नहीं पड़ता कि इन क्रियाओं का प्रवाह क्या होगा, मुख्य बात यह है कि वे एक ही मॉनिटर, अस्थिर चर पर हैं। SW थ्रेड्स के बीच एक पुल प्रदान करता है।

और अब हम सबसे दिलचस्प क्रम में आते हैं - हैपन्स-बिफोर ( एचबी )।
HB , SW और PO के मिलन का एक सकर्मक समापन है। पीओ धारा के भीतर एक रैखिक आदेश देता है, और एसडब्ल्यू धाराओं के बीच एक पुल प्रदान करता है। एचबी सकर्मक है, अर्थात अगर

 x HB y  y HB z,  x HB z 

विनिर्देश में एचबी संबंधों की एक सूची है, आप अपने आप को इसके साथ और अधिक विस्तार से परिचित कर सकते हैं, यहां कुछ सूची हैं:

एक सूत्र के भीतर, कोई भी ऑपरेशन होता है-सोर्स कोड में किसी भी ऑपरेशन के बाद।

एक सिंक्रनाइज़ किए गए ब्लॉक / विधि से बाहर निकलना होता है-एक ही मॉनिटर पर एक सिंक्रनाइज़ ब्लॉक / विधि में प्रवेश करने से पहले।

एक वाष्पशील क्षेत्र लिखना होता है-एक ही वाष्पशील क्षेत्र को पढ़ने से पहले।

आइए अपने उदाहरण पर वापस आते हैं:

 P: a = 1 PO x = b Q: b = 1 PO y = a 

आइए अपने उदाहरण पर वापस जाएं और आदेशों को ध्यान में रखते हुए कार्यक्रम का विश्लेषण करने का प्रयास करें।

जेएमएम का उपयोग करके कार्यक्रम का विश्लेषण किसी भी परिकल्पना को आगे बढ़ाने और उनकी पुष्टि या खंडन करने पर आधारित है।



हम अपने विश्लेषण की परिकल्पना के साथ शुरू करते हैं कि एक भी कार्यक्रम निष्पादन परिणाम (0, 0) नहीं देता है। सभी निष्पादन पर परिणाम (0, 0) की अनुपस्थिति कार्यक्रम की एक अपेक्षित संपत्ति है।

हम विभिन्न निष्पादन का निर्माण करके परिकल्पना का परीक्षण करते हैं।

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

हम एक छोटा सा आरक्षण करते हैं।

चूंकि आम चर पर सभी क्रियाएं हमारे लिए महत्वपूर्ण हैं, और उदाहरण में, सामान्य चर एक, बी, एक्स, वाई हैं । फिर, उदाहरण के लिए, ऑपरेशन एक्स = बी को आर (बी) और डब्ल्यू (एक्स, बी) के रूप में माना जाना चाहिए, और r(b) HB w(x,b) ( पीओ पर आधारित) है। लेकिन चूंकि चर एक्स थ्रेड्स में कहीं भी पढ़ा नहीं गया है (कोड के अंत में प्रिंट में पढ़ना दिलचस्प नहीं है, क्योंकि थ्रेड पर शामिल होने के ऑपरेशन के बाद हम मूल्य एक्स देखेंगे), हम एक्शन डब्ल्यू (एक्स, बी) पर विचार नहीं कर सकते हैं।

पहले प्रदर्शन की जाँच करें।

 w(a, 1) HB r(b): 0 … w(b, 1) HB r(a): 0 

स्ट्रीम Q में, हम वेरिएबल a पढ़ते हैं, इस वेरिएबल को स्ट्रीम P में लिखते हैं लिखने और पढ़ने (पीओ, एसडब्ल्यू, एचबी) के बीच कोई आदेश नहीं है।

यदि चर एक थ्रेड में लिखा गया है और रीडिंग किसी अन्य थ्रेड में है और कार्रवाई के बीच कोई HB संबंध नहीं है, तो वे कहते हैं कि चर रेस के तहत पढ़ा जाता है। और जेएमएम के अनुसार दौड़ के तहत हम एचबी में पिछले दर्ज किए गए मूल्य या किसी अन्य मूल्य को पढ़ सकते हैं।

ऐसा प्रदर्शन संभव है। निष्पादन झामुमो का उल्लंघन नहीं करता है । चर को पढ़ते समय, आप किसी भी मूल्य को देख सकते हैं, क्योंकि पढ़ना दौड़ के तहत होता है और इस बात की कोई गारंटी नहीं है कि हम कार्रवाई को देखेंगे (ए, 1)। इसका मतलब यह नहीं है कि कार्यक्रम सही ढंग से काम करता है, इसका सीधा मतलब है कि इस तरह के परिणाम की उम्मीद है।

यह बाकी निष्पादन पर विचार करने के लिए कोई मतलब नहीं है, क्योंकि परिकल्पना पहले से ही नष्ट हो गई है

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

यह साबित करने के लिए कि कार्यक्रम गैर-रेसिंग है, आपको सभी प्रदर्शनों के लिए ऐसा करने की आवश्यकता है। आइए एक अस्थिर संशोधक के साथ एसए और मार्क चर बनाने की कोशिश करें। अस्थिर चर v के साथ उपसर्ग किए जाएंगे।

हमने एक नई परिकल्पना को सामने रखा। यदि चर को अस्थिर बनाया जाता है, तो कार्यक्रम का कोई भी निष्पादन परिणाम (0, 0) नहीं देगा।

 w(va, 1) HB r(b): 0 … w(b, 1) HB r(va): 0 

निष्पादन झामुमो का उल्लंघन नहीं करता है । वाया पढ़ना रेस के तहत होता है। कोई भी दौड़ HB की संक्रामकता को नष्ट कर देती है।

हमने एक और परिकल्पना सामने रखी। यदि चर बी को अस्थिर किया जाता है , तो कार्यक्रम का कोई भी निष्पादन परिणाम (0, 0) नहीं देगा।

 w(a, 1) HB r(vb): 0 … w(vb, 1) HB r(a): 0 

निष्पादन झामुमो का उल्लंघन नहीं करता है। दौड़ के तहत होता है पढ़ना।

आइए परिकल्पना का परीक्षण करें कि यदि चर ए और बी अस्थिर हैं , तो कोई भी कार्यक्रम निष्पादन परिणाम (0, 0) नहीं देगा।

पहले प्रदर्शन की जाँच करें।

 w(va, 1) SO r(vb): 0 SO w(vb, 1) SO r(va): 0 

चूंकि SA कार्यक्रम में सभी क्रियाएं (विशेष रूप से वाष्पशील चर को पढ़ना या लिखना), हमें सभी क्रियाओं के बीच पूर्ण SO क्रम मिलता है। इसका अर्थ है कि r (va) को w (va, 1) देखना चाहिए। यह निष्पादन JMM का उल्लंघन करता है

परिकल्पना की पुष्टि करने के लिए अगले निष्पादन के लिए आगे बढ़ना आवश्यक है। लेकिन चूंकि किसी भी निष्पादन के लिए एसओ होगा, आप औपचारिकता से विचलन कर सकते हैं - यह स्पष्ट है कि परिणाम (0, 0) किसी भी निष्पादन के लिए झामुमो का उल्लंघन करता है।

रोटेशन मॉडल का उपयोग करने के लिए, आपको चर ए और बी के लिए अस्थिर जोड़ने की आवश्यकता है। ऐसा कार्यक्रम परिणाम (1,1), (1,0) या (0,1) देगा।

अंत में, हम कह सकते हैं कि विश्लेषण के लिए बहुत सरल कार्यक्रम काफी सरल हैं।

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

अन्य प्रतिस्पर्धी निष्पादन मॉडल


अन्य प्रतिस्पर्धी प्रोग्रामिंग मॉडल पर विचार क्यों करें?

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

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

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

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

ऊपर दिए गए प्रश्न का उत्तर देना। जहां तक ​​मैं समझता हूं, प्रतिस्पर्धी प्रोग्रामिंग मॉडल हैं जो कम से कम जेएमएम की बारीकियों के ज्ञान की आवश्यकता को कम कर सकते हैं। हालाँकि, यदि कोई परिवर्तनशील स्थिति है और प्रवाहित होती है, तो उन पर किसी भी तरह के दबाव को कम न करें, फिर भी एक स्थान ऐसा होगा जहाँ इन प्रवाह को राज्य तक पहुँच को सिंक्रनाइज़ करना चाहिए। एक अन्य प्रश्न यह है कि संभवतः आपको अपने आप को एक्सेस करने के लिए सिंक्रोनाइज़ नहीं करना पड़ता है, उदाहरण के लिए, एक फ्रेमवर्क इसके लिए उत्तर दे सकता है। लेकिन जैसा कि हमने कहा है, अभी या बाद में, अमूर्तता हो सकती है।

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

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

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

हालांकि, एक अभिनेता आंतरिक स्थिति को बदल सकता है। यह देखते हुए कि समय पर अगले क्षण में, एक ही अभिनेता को दूसरे धागे पर निष्पादित किया जा सकता है, यह एक समस्या हो सकती है। समस्या को अलग-अलग तरीकों से हल किया जा सकता है, प्रोग्रामिंग भाषाओं में जैसे एर्लांग या एलिक्सिर, जहां अभिनेता मॉडल भाषा का एक अभिन्न अंग है, आप एक नए राज्य के साथ अभिनेता को कॉल करने के लिए पुनरावर्तन का उपयोग कर सकते हैं।

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

थ्रेडिंग मॉडल इतना लोकप्रिय क्यों है?


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

लेकिन फिर भी धागे और ताले अभी भी इतने लोकप्रिय क्यों हैं?

मुझे लगता है कि इसका कारण दृष्टिकोण की सादगी है, ज़ाहिर है, एक तरफ, धाराओं के साथ बहुत सी गलतियाँ करना आसान है, पैर में खुद को गोली मारना, आदि। लेकिन दूसरी ओर , प्रवाह में कुछ भी जटिल नहीं है, खासकर यदि आप परिणामों के बारे में नहीं सोचते हैं

एक समय में, कर्नेल एक निर्देश को निष्पादित कर सकता है (वास्तव में, संक्षिप्तता अनुदेश स्तर पर मौजूद नहीं है, लेकिन अब यह महत्वपूर्ण नहीं है), लेकिन मल्टीटास्किंग के कारण, यहां तक ​​कि एकल-कोर मशीनों पर भी, कई कार्यक्रमों को एक साथ निष्पादित किया जा सकता है (पाठ्यक्रम के छद्म एक साथ)।

मल्टीटास्किंग काम करने के लिए, आपको प्रतियोगिता की आवश्यकता है। जैसा कि हमने पहले ही पता लगा लिया है, कई प्रबंधन प्रवाह के बिना प्रतियोगिता असंभव है।

आप कितने धागे सोचते हैं कि क्वाड-कोर मोबाइल फोन प्रोसेसर पर चलने वाला प्रोग्राम जितना संभव हो उतना तेज़ और उत्तरदायी होना चाहिए?

कई दर्जन हो सकते हैं। अब सवाल यह है कि हार्डवेयर पर चलने वाले प्रोग्राम के लिए हमें इतने सारे थ्रेड्स की आवश्यकता क्यों है जो आपको एक समय में केवल 2-4 थ्रेड निष्पादित करने की अनुमति देता है?

इस प्रश्न का उत्तर देने की कोशिश करने के लिए, मान लीजिए कि केवल हमारा कार्यक्रम डिवाइस पर चल रहा है और कुछ नहीं। हम हमें प्रदान किए गए संसाधनों का प्रबंधन कैसे करेंगे?

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

समस्या को हल करने के लिए क्या प्रौद्योगिकियां हैं?

जावा में थ्रेड्स हैं, हम कई थ्रेड्स बना सकते हैं, और फिर अन्य थ्रेड्स ऑपरेशन करने में सक्षम होंगे, जबकि कुछ थ्रेड्स अवरुद्ध हैं। धागे जैसे उपकरण से हम अपने जीवन को सरल बना सकते हैं।

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

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

धाराएं न केवल बैकएंड विकास में लोकप्रिय हैं, बल्कि मोबाइल विकास में भी दर्जनों धाराएँ बनाना काफी सामान्य माना जाता है ताकि आप कुछ सेकंड के लिए स्ट्रीम को ब्लॉक कर सकें, नेटवर्क पर डेटा डाउनलोड होने या सॉकेट से डेटा डाउनलोड होने की प्रतीक्षा करें।

Erlang या Clojure जैसी भाषाएँ अभी भी आला हैं, और इसलिए प्रतिस्पर्धी प्रोग्रामिंग मॉडल जो वे उपयोग करते हैं, वे इतने लोकप्रिय नहीं हैं। हालांकि, उनके लिए पूर्वानुमान सबसे अधिक आशावादी हैं।

निष्कर्ष


यदि आप जेवीएम प्लेटफॉर्म पर विकसित हो रहे हैं, तो आपको प्लेटफॉर्म द्वारा इंगित गेम के नियमों को स्वीकार करने की आवश्यकता है। यह सामान्य मल्टीथ्रेड कोड लिखने का एकमात्र तरीका है। यह सब कुछ के संदर्भ को समझने के लिए बहुत ही वांछनीय है, इसलिए खेल के नियमों को स्वीकार करना आसान होगा। आसपास देखना और अन्य प्रतिमानों से परिचित होना और भी बेहतर है, हालाँकि आप पनडुब्बी से कहीं भी नहीं जा सकते, लेकिन आप नए तरीकों और उपकरणों की खोज कर सकते हैं।

अतिरिक्त सामग्री


मैंने लेख लिंक के पाठ को उन स्रोतों से जोड़ने की कोशिश की जिनसे मुझे जानकारी मिली।

सामान्य तौर पर, जेएमएम सामग्री इंटरनेट पर ढूंढना आसान है। यहाँ मैं कुछ अतिरिक्त सामग्री के लिंक पोस्ट करूँगा जो JMM से जुड़ी है और शायद मेरी नज़र को पकड़ न पाएं।

पढ़ना

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

पॉडकास्ट के

मुद्दे जो मुझे विशेष रूप से दिलचस्प लगे। वे झामुमो के बारे में नहीं हैं, वे नर्क के बारे में हैं, जो ग्रंथि में हो रहा है। लेकिन उन्हें सुनने के बाद, मैं झामुमो के रचनाकारों, जो हम सभी को इस से बचाने के हाथों को चूम करना चाहते हैं।


वीडियो

उपर्युक्त लोगों के भाषणों के अलावा, शैक्षणिक वीडियो पर ध्यान दें।

Source: https://habr.com/ru/post/hi440590/


All Articles