ऑब्जेक्ट पूल पैटर्न: Difference between revisions

From Vigyanwiki
No edit summary
No edit summary
Line 1: Line 1:
{{for|एक सामान्य पूल के विषय में लेख|पूल (कंप्यूटर विज्ञान)}}
{{for|एक सामान्य पूल के विषय में लेख|पूल (कंप्यूटर विज्ञान)}}


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


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


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


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


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


ऑब्जेक्ट पूल डिज़ाइन पैटर्न का उपयोग .NET फ्रेमवर्क के मानक वर्गों में कई स्थानों पर किया जाता है। एक उदाहरण एसक्यूएल सर्वर के लिए .NET फ्रेमवर्क डेटा प्रदाता है। चूंकि एसक्यूएल सर्वर डेटाबेस कनेक्शन बनाने में धीमा हो सकता है, कनेक्शन का पूल बनाए रखा जाता है। कनेक्शन बंद करना वास्तव में एसक्यूएल सर्वर से लिंक को त्यागना नहीं है। इसके अतिरिक्त, कनेक्शन को पूल में रखा जाता है, जिससे नए कनेक्शन का अनुरोध करते समय इसे पुनर्प्राप्त किया जा सकता है। यह कनेक्शन बनाने की गति को काफी हद तक बढ़ा देता है।
ऑब्जेक्ट पूल डिज़ाइन पैटर्न का उपयोग डॉटनेट फ्रेमवर्क के मानक वर्गों में कई स्थानों पर किया जाता है। एक उदाहरण एसक्यूएल सर्वर के लिए डॉटनेट फ्रेमवर्क डेटा प्रदाता है। चूंकि एसक्यूएल सर्वर डेटाबेस संयोजन बनाने में अपेक्षाकृत धीमा हो सकता है, डेटा संबंध का पूल बनाए रखा जाता है। डेटा संबंध को स्थगित करना वास्तव में एसक्यूएल सर्वर से लिंक को अलग करना नहीं होता है। इसके अतिरिक्त, डेटा संबंध को पूल में रखा जाता है जिससे नए डेटा संबंध का अनुरोध करते समय इसे पुनर्प्राप्त किया जा सकता है। यह डेटा संबंध बनाने की गति को अपेक्षाकृत रूप से अत्यधिक विस्तृत करता है।


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


पूल की गई वस्तु अनुमानित समय में प्राप्त होती है जब नई वस्तुओं (विशेष रूप से नेटवर्क पर) के निर्माण में परिवर्तनशील समय लग सकता है। ये लाभ अधिकतर उन वस्तुओं के लिए सही हैं जो समय के साथ महंगे हैं, जैसे डेटाबेस कनेक्शन, सॉकेट कनेक्शन, थ्रेड्स और बड़े ग्राफिक ऑब्जेक्ट्स जैसे फोंट या बिटमैप्स।
पूल की गई वस्तु अनुमानित समय में प्राप्त होती है जब नई वस्तुओं (विशेष रूप से नेटवर्क पर) के निर्माण में परिवर्तनशील समय लग सकता है। ये लाभ अधिकाश उन वस्तुओं के लिए सही हैं जो समय के साथ कीमती हैं जैसे डेटाबेस संबंध, सॉकेट डेटा संबंध, थ्रेड्स और बड़े ग्राफिक ऑब्जेक्ट्स जैसे फोंट या बिटमैप्स और अन्य स्थितियों में, साधारण ऑब्जेक्ट पूलिंग (जिसमें कोई बाहरी संसाधन नहीं होता है, लेकिन केवल मेमोरी पर अधिकृत होता है) कुशल नहीं हो सकता है और प्रदर्शन को कम कर सकता है।<ref name="urban">{{cite web|last1=Goetz|first1=Brian|date=2005-09-27|title=Java theory and practice: Urban performance legends, revisited|url=http://www.ibm.com/developerworks/java/library/j-jtp09275/index.html|url-status=dead|archive-url=https://web.archive.org/web/20120214195433/http://www.ibm.com/developerworks/java/library/j-jtp09275/index.html|archive-date=2012-02-14|access-date=2021-03-15|website=[[IBM]]|publisher=IBM developerWorks}}</ref> साधारण मेमोरी पूलिंग की स्थितिे में, [[स्लैब आवंटन]] मेमोरी प्रबंधन तकनीक अधिक अनुकूल है, क्योंकि एकमात्र मेमोरी विखंडन (फ्रैग्मेंटेशन) को कम करके मेमोरी आवंटन और डीलोकेशन की लागत को कम किया जा सकता है।
 
अन्य स्थितियों में, साधारण ऑब्जेक्ट पूलिंग (जिसमें कोई बाहरी संसाधन नहीं होता है, लेकिन केवल स्मृति पर कब्जा होता है) कुशल नहीं हो सकता है और प्रदर्शन को कम कर सकता है।<ref name="urban">{{cite web|last1=Goetz|first1=Brian|date=2005-09-27|title=Java theory and practice: Urban performance legends, revisited|url=http://www.ibm.com/developerworks/java/library/j-jtp09275/index.html|url-status=dead|archive-url=https://web.archive.org/web/20120214195433/http://www.ibm.com/developerworks/java/library/j-jtp09275/index.html|archive-date=2012-02-14|access-date=2021-03-15|website=[[IBM]]|publisher=IBM developerWorks}}</ref> साधारण मेमोरी पूलिंग के स्थितिे में, [[स्लैब आवंटन]] मेमोरी प्रबंधन तकनीक अधिक अनुकूल है, क्योंकि एकमात्र लक्ष्य विखंडन को कम करके मेमोरी आवंटन और डीलोकेशन की लागत को कम करना है।


== कार्यान्वयन ==
== कार्यान्वयन ==
ऑब्जेक्ट पूल को [[ स्मार्ट सूचक |स्मार्ट पॉइंटर्स]] के माध्यम से सी ++ जैसी भाषाओं में स्वचालित तरीके से कार्यान्वित किया जा सकता है। स्मार्ट पॉइंटर के कंस्ट्रक्टर में, ऑब्जेक्ट को पूल से रिक्वेस्ट किया जा सकता है, और स्मार्ट पॉइंटर के डिस्ट्रक्टर में, ऑब्जेक्ट को पूल में वापस छोड़ा जा सकता है। कचरा एकत्र करने वाली भाषाओं में, जहां कोई विध्वंसक नहीं है (जो स्टैक अनविंड के हिस्से के रूप में कहे जाने की गारंटी है), ऑब्जेक्ट पूल को मैन्युअल रूप से लागू किया जाना चाहिए, स्पष्ट रूप से [[ फैक्टरी (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) |फैक्टरी (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)]] से किसी वस्तु का अनुरोध करके और निपटान विधि को कॉल करके वस्तु को वापस करना। (डिस्पोज पैटर्न के अनुसार)। ऐसा करने के लिए [[finalizer|फ़ाइनलाइज़र]] का उपयोग करना एक अच्छा विचार नहीं है, क्योंकि फ़ाइनलाइज़र कब (या यदि) चलाया जाएगा, इसकी कोई गारंटी नहीं है। इसके अतिरिक्त, "कोशिश करें ... अंत में" का उपयोग यह सुनिश्चित करने के लिए किया जाना चाहिए कि वस्तु प्राप्त करना और जारी करना अपवाद-तटस्थ है।
ऑब्जेक्ट पूल को [[ स्मार्ट सूचक |पॉइंटर]] (प्रोग्रामिंग) के माध्यम से सी ++ जैसी भाषाओं में स्वचालित तरीके से कार्यान्वित किया जा सकता है। पॉइंटर के निर्माण में, ऑब्जेक्ट को पूल से अनुरोध किया जा सकता है और पॉइंटर को नष्ट करने के लिए, ऑब्जेक्ट को पूल में वापस भेजा जा सकता है। गार्बेज़ डेटा एकत्र करने वाली भाषाओं में, जहां कोई विध्वंसक नहीं है जो स्टैक-अनविंड के भाग के रूप में कहे जाने का दायित्व है ऑब्जेक्ट पूल को मैन्युअल रूप से प्रयुक्त किया जाना चाहिए, स्पष्ट रूप से [[ फैक्टरी (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) |फैक्टरी (वस्तु-उन्मुख प्रोग्रामिंग)]] से किसी भी वस्तु का अनुरोध करके और डिस्पोस विधि को कॉल करके वस्तु को वापस करना सम्मिलित होता है डिस्पोज पैटर्न के अनुसार ऐसा करने के लिए [[finalizer|फ़ाइनलाइज़र]] का उपयोग करना एक अपेक्षाकृत रूप से अच्छा नहीं है क्योंकि फ़ाइनलाइज़र कब सक्रिय किया जा सकता है इसका कोई निर्धारित समय नहीं होता है।  
 
मैनुअल ऑब्जेक्ट पूल को लागू करना सरल है, लेकिन उपयोग करना कठिन है, क्योंकि उन्हें पूल ऑब्जेक्ट के मैन्युअल मेमोरी प्रबंधन की आवश्यकता होती है।


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


ऑब्जेक्ट पूल अनुरोध को संभालने के लिए तीन रणनीतियों में से एक को नियोजित करता है जब पूल में कोई अतिरिक्त वस्तु नहीं होती है।
== रिक्त पूल संचालन ==


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


== नुकसान ==
# ऑब्जेक्ट प्रदान करने में विफलता (उपयोगकर्ता को एक त्रुटि देना)।
# एक नई वस्तु आवंटित करें, जिससे पूल का आकार विस्तृत हो जाए ऐसा करने वाले पूल समान्यतः आपको उच्च संकेत (कभी उपयोग की जाने वाली वस्तुओं की अधिकतम संख्या) समूह का प्रयोग करने की स्वीकृति देते हैं।
# थ्रेड (कंप्यूटर विज्ञान) में, एक पूल उपयोगकर्ता को तब तक ब्लॉक कर सकता है जब तक कि कोई अन्य थ्रेड किसी ऑब्जेक्ट को पूल में वापस नहीं कर देता है।


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


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


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


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


== आलोचना ==
== समीक्षा ==
कुछ प्रकाशन कुछ भाषाओं, जैसे [[जावा (प्रोग्रामिंग भाषा)]] के साथ ऑब्जेक्ट पूलिंग का उपयोग करने की अनुशंसा नहीं करते हैं, विशेष रूप से उन वस्तुओं के लिए जो केवल मेमोरी का उपयोग करते हैं और कोई बाहरी संसाधन नहीं रखते हैं (जैसे डेटाबेस से कनेक्शन)विरोधी आमतौर पर कहते हैं कि [[कचरा संग्रह (कंप्यूटर विज्ञान)]] के साथ आधुनिक भाषाओं में वस्तु आवंटन अपेक्षाकृत तेज़ है; जबकि ऑपरेटर <code>new</code> केवल दस निर्देशों की जरूरत है, क्लासिक <code>new</code> - <code>delete</code> पूलिंग डिज़ाइन में पाई जाने वाली जोड़ी को उनमें से सैकड़ों की आवश्यकता होती है क्योंकि यह अधिक जटिल कार्य करता है। इसके अलावा, अधिकांश कचरा संग्राहक लाइव ऑब्जेक्ट संदर्भों को स्कैन करते हैं, न कि उस मेमोरी को जो ये ऑब्जेक्ट अपनी सामग्री के लिए उपयोग करते हैं। इसका तात्पर्य यह है कि संदर्भ के बिना किसी भी संख्या में मृत वस्तुओं को बहुत कम लागत के साथ त्याग दिया जा सकता है। इसके विपरीत, बड़ी संख्या में जीवित लेकिन अप्रयुक्त वस्तुओं को रखने से कचरा संग्रह की अवधि बढ़ जाती है।<ref name="urban" />
कुछ प्रकाशन कुछ भाषाओं, जैसे [[जावा (प्रोग्रामिंग भाषा)]] के साथ ऑब्जेक्ट पूलिंग का उपयोग करने की अपेक्षा नहीं करते हैं, विशेष रूप से उन वस्तुओं के लिए जो केवल मेमोरी का उपयोग करते हैं और कोई बाहरी संसाधन (जैसे डेटाबेस से डेटा संबंध) नहीं रखते हैं। विरोधी समान्यतः कहते हैं कि [[कचरा संग्रह (कंप्यूटर विज्ञान)|गार्बेज़ डेटा (कंप्यूटर विज्ञान)]] के साथ आधुनिक भाषाओं में वस्तु आवंटन अपेक्षाकृत तीव्र है जबकि ऑपरेटर <code>new</code> केवल दस निर्देशों की आवश्यकता है, क्लासिक <code>new</code> - <code>delete</code> पूलिंग डिज़ाइन में पाई जाने वाली जोड़ी को उनमें से सैकड़ों की आवश्यकता होती है क्योंकि यह अधिक जटिल कार्य करता है। इसके अतिरिक्त, अधिकांश गार्बेज़ संग्राहक लाइव ऑब्जेक्ट संदर्भों का अवलोकन करते हैं, न कि उस मेमोरी को जो ये ऑब्जेक्ट डेटा के लिए उपयोग करते हैं। इसका तात्पर्य यह है कि संदर्भ के बिना किसी भी संख्या में निष्क्रिय वस्तुओं को बहुत कम लागत के साथ नियोजित कर दिया जा सकता है। इसके विपरीत, बड़ी संख्या में अप्रयुक्त वस्तुओं को रखने से गार्बेज़ डेटा की अवधि विस्तृत हो जाती है।<ref name="urban" />
== उदाहरण ==
== उदाहरण ==


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


<syntaxhighlight lang=Go>
<syntaxhighlight lang=Go>
Line 166: Line 162:
}
}
</syntaxhighlight>
</syntaxhighlight>
=== सी # ===
=== सी # ===
.NET [[बेस क्लास लाइब्रेरी]] में कुछ ऑब्जेक्ट हैं जो इस पैटर्न को लागू करते हैं। <code>System.Threading.ThreadPool</code> आवंटित करने के लिए धागे की पूर्वनिर्धारित संख्या के लिए कॉन्फ़िगर किया गया है। जब धागे लौटाए जाते हैं, तो वे दूसरी गणना के लिए उपलब्ध होते हैं। इस प्रकार, थ्रेड्स के निर्माण और निपटान की लागत का भुगतान किए बिना थ्रेड्स का उपयोग किया जा सकता है।
.NET [[बेस क्लास लाइब्रेरी]] में कुछ ऑब्जेक्ट हैं जो इस पैटर्न को लागू करते हैं। <code>System.Threading.ThreadPool</code> को आवंटित करने के लिए थ्रेड्स की पूर्वनिर्धारित संख्या के लिए कॉन्फ़िगर किया गया है। जब डेटा को वापस किया जाता हैं तो वे दूसरी गणना के लिए उपलब्ध होते हैं। इस प्रकार, थ्रेड्स के निर्माण की लागत का भुगतान किए बिना थ्रेड्स का उपयोग किया जा सकता है।


निम्नलिखित सी # का उपयोग करके कार्यान्वित ऑब्जेक्ट पूल डिज़ाइन पैटर्न का मूल कोड दिखाता है। संक्षिप्तता के लिए कक्षाओं के गुणों को सी # 3.0 स्वचालित रूप से कार्यान्वित संपत्ति सिंटैक्स का उपयोग करके घोषित किया जाता है। इन्हें भाषा के पुराने संस्करणों के लिए पूर्ण संपत्ति परिभाषाओं से बदला जा सकता है। पूल को एक स्थिर वर्ग के रूप में दिखाया गया है, क्योंकि कई पूलों की आवश्यकता होना असामान्य है। हालाँकि, ऑब्जेक्ट पूल के लिए इंस्टेंस क्लास का उपयोग करना समान रूप से स्वीकार्य है।
निम्नलिखित सी # का उपयोग करके कार्यान्वित ऑब्जेक्ट पूल डिज़ाइन पैटर्न का मूल कोड प्रदर्शित किया जा सकता है। संक्षिप्तता के लिए कक्षाओं के गुणों को सी # 3.0 स्वचालित रूप से कार्यान्वित सिंटैक्स का उपयोग करके घोषित किया जाता है। इन्हें भाषा के पुराने संस्करणों के लिए पूर्ण रूप से परिभाषाओं से परिवर्तित किया जा सकता है। पूल को एक स्थिर वर्ग के रूप में प्रदर्शित किया गया है क्योंकि कई पूलों की आवश्यकता होना असामान्य है। हालाँकि, ऑब्जेक्ट पूल के लिए "इंस्टेंस क्लास" का उपयोग करना समान रूप से स्वीकार्य होता है।
<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
namespace DesignPattern.Objectpool;
namespace DesignPattern.Objectpool;
Line 234: Line 228:
}
}
</syntaxhighlight>
</syntaxhighlight>
ऊपर दिए गए कोड में, पूलेडऑब्जेक्ट में उस समय के लिए गुण होते हैं जब इसे बनाया गया था, और दूसरा, जिसे क्लाइंट द्वारा संशोधित किया जा सकता है, जिसे पूल में वापस जारी किए जाने पर रीसेट किया जाता है। दिखाया गया है क्लीन-अप प्रक्रिया, किसी वस्तु को जारी करने पर, यह सुनिश्चित करने से पहले कि पूल से फिर से अनुरोध किया जा सकता है, यह एक वैध स्थिति में है।
ऊपर दिए गए कोड में, पूल ऑब्जेक्ट में उस समय के लिए गुण होते हैं जब इसे बनाया गया था और दूसरा, जिसे उपयोगकर्ता द्वारा संशोधित किया जा सकता है, पूल में वापस प्रारम्भ किए जाने पर रीसेट किया जाता है। यह दिखाया गया है <code>CleanUp</code> प्रक्रिया, किसी वस्तु को प्रारम्भ करने पर, यह सुनिश्चित करने से पहले कि पूल से फिर से अनुरोध किया जा सकता है, यह एक वैध स्थिति में होता है।


=== जावा ===
=== जावा ===
जावा [[थ्रेड पूल पैटर्न]] का समर्थन करता है <code>java.util.concurrent.ExecutorService</code> और अन्य संबंधित वर्ग। निष्पादक सेवा में एक निश्चित संख्या में मूल सूत्र होते हैं जिन्हें कभी नहीं छोड़ा जाता है। यदि सभी धागे व्यस्त हैं, तो सेवा अतिरिक्त धागे की अनुमत संख्या आवंटित करती है जिन्हें बाद में छोड़ दिया जाता है यदि निश्चित समाप्ति समय के लिए उपयोग नहीं किया जाता है। यदि अधिक थ्रेड्स की स्वीकृति नहीं है, तो कार्यों को कतार में रखा जा सकता है। अंत में, यदि यह कतार बहुत लंबी हो सकती है, तो अनुरोध करने वाले थ्रेड को निलंबित करने के लिए इसे कॉन्फ़िगर किया जा सकता है।
जावा <code>java.util.concurrent.ExecutorService</code> और अन्य संबंधित वर्गों के माध्यम से [[थ्रेड पूल पैटर्न]] का समर्थन करता है। निष्पादक सेवा में एक निश्चित संख्या में "मूल" कोड होते हैं जिन्हें कभी नहीं छोड़ा जाता है। यदि सभी कोड मुक्त हैं तो सेवा अतिरिक्त कोड की अनुमत संख्या आवंटित करती है जिन्हें बाद में छोड़ दिया जाता है यदि निश्चित समाप्ति समय के लिए उपयोग नहीं किया जाता है। यदि अधिक थ्रेड्स की स्वीकृति नहीं है, तो कार्यों को पंक्ति में रखा जा सकता है। अंत में, यदि यह पंक्ति बहुत लंबी हो सकती है तो अनुरोध करने वाले थ्रेड को निलंबित करने के लिए इसे कॉन्फ़िगर किया जा सकता है।


<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
Line 328: Line 322:
</syntaxhighlight>
</syntaxhighlight>
== यह भी देखें ==
== यह भी देखें ==
* [[कनेक्शन पूल]]
* [[कनेक्शन पूल|डेटा संबंध पूल]]
* [[मुफ्त सूची]]
* [[मुफ्त सूची]]
* स्लैब आवंटन
* स्लैब आवंटन

Revision as of 10:33, 7 March 2023

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

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

विवरण

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

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

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

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

लाभ

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

पूल की गई वस्तु अनुमानित समय में प्राप्त होती है जब नई वस्तुओं (विशेष रूप से नेटवर्क पर) के निर्माण में परिवर्तनशील समय लग सकता है। ये लाभ अधिकाश उन वस्तुओं के लिए सही हैं जो समय के साथ कीमती हैं जैसे डेटाबेस संबंध, सॉकेट डेटा संबंध, थ्रेड्स और बड़े ग्राफिक ऑब्जेक्ट्स जैसे फोंट या बिटमैप्स और अन्य स्थितियों में, साधारण ऑब्जेक्ट पूलिंग (जिसमें कोई बाहरी संसाधन नहीं होता है, लेकिन केवल मेमोरी पर अधिकृत होता है) कुशल नहीं हो सकता है और प्रदर्शन को कम कर सकता है।[1] साधारण मेमोरी पूलिंग की स्थितिे में, स्लैब आवंटन मेमोरी प्रबंधन तकनीक अधिक अनुकूल है, क्योंकि एकमात्र मेमोरी विखंडन (फ्रैग्मेंटेशन) को कम करके मेमोरी आवंटन और डीलोकेशन की लागत को कम किया जा सकता है।

कार्यान्वयन

ऑब्जेक्ट पूल को पॉइंटर (प्रोग्रामिंग) के माध्यम से सी ++ जैसी भाषाओं में स्वचालित तरीके से कार्यान्वित किया जा सकता है। पॉइंटर के निर्माण में, ऑब्जेक्ट को पूल से अनुरोध किया जा सकता है और पॉइंटर को नष्ट करने के लिए, ऑब्जेक्ट को पूल में वापस भेजा जा सकता है। गार्बेज़ डेटा एकत्र करने वाली भाषाओं में, जहां कोई विध्वंसक नहीं है जो स्टैक-अनविंड के भाग के रूप में कहे जाने का दायित्व है ऑब्जेक्ट पूल को मैन्युअल रूप से प्रयुक्त किया जाना चाहिए, स्पष्ट रूप से फैक्टरी (वस्तु-उन्मुख प्रोग्रामिंग) से किसी भी वस्तु का अनुरोध करके और डिस्पोस विधि को कॉल करके वस्तु को वापस करना सम्मिलित होता है डिस्पोज पैटर्न के अनुसार ऐसा करने के लिए फ़ाइनलाइज़र का उपयोग करना एक अपेक्षाकृत रूप से अच्छा नहीं है क्योंकि फ़ाइनलाइज़र कब सक्रिय किया जा सकता है इसका कोई निर्धारित समय नहीं होता है।

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

रिक्त पूल संचालन

ऑब्जेक्ट पूल अनुरोध को संरक्षित करने के लिए तीन कूटनीतियों में से एक को नियोजित किया जा सकता है जब पूल में कोई अतिरिक्त वस्तु नहीं होती है।

  1. ऑब्जेक्ट प्रदान करने में विफलता (उपयोगकर्ता को एक त्रुटि देना)।
  2. एक नई वस्तु आवंटित करें, जिससे पूल का आकार विस्तृत हो जाए ऐसा करने वाले पूल समान्यतः आपको उच्च संकेत (कभी उपयोग की जाने वाली वस्तुओं की अधिकतम संख्या) समूह का प्रयोग करने की स्वीकृति देते हैं।
  3. थ्रेड (कंप्यूटर विज्ञान) में, एक पूल उपयोगकर्ता को तब तक ब्लॉक कर सकता है जब तक कि कोई अन्य थ्रेड किसी ऑब्जेक्ट को पूल में वापस नहीं कर देता है।

हानि

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

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

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

समीक्षा

कुछ प्रकाशन कुछ भाषाओं, जैसे जावा (प्रोग्रामिंग भाषा) के साथ ऑब्जेक्ट पूलिंग का उपयोग करने की अपेक्षा नहीं करते हैं, विशेष रूप से उन वस्तुओं के लिए जो केवल मेमोरी का उपयोग करते हैं और कोई बाहरी संसाधन (जैसे डेटाबेस से डेटा संबंध) नहीं रखते हैं। विरोधी समान्यतः कहते हैं कि गार्बेज़ डेटा (कंप्यूटर विज्ञान) के साथ आधुनिक भाषाओं में वस्तु आवंटन अपेक्षाकृत तीव्र है जबकि ऑपरेटर new केवल दस निर्देशों की आवश्यकता है, क्लासिक new - delete पूलिंग डिज़ाइन में पाई जाने वाली जोड़ी को उनमें से सैकड़ों की आवश्यकता होती है क्योंकि यह अधिक जटिल कार्य करता है। इसके अतिरिक्त, अधिकांश गार्बेज़ संग्राहक लाइव ऑब्जेक्ट संदर्भों का अवलोकन करते हैं, न कि उस मेमोरी को जो ये ऑब्जेक्ट डेटा के लिए उपयोग करते हैं। इसका तात्पर्य यह है कि संदर्भ के बिना किसी भी संख्या में निष्क्रिय वस्तुओं को बहुत कम लागत के साथ नियोजित कर दिया जा सकता है। इसके विपरीत, बड़ी संख्या में अप्रयुक्त वस्तुओं को रखने से गार्बेज़ डेटा की अवधि विस्तृत हो जाती है।[1]

उदाहरण

गो (प्रोग्रामिंग भाषा)

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

// package pool
package pool

import (
	"errors"
	"log"
	"math/rand"
	"sync"
	"time"
)

const getResMaxTime = 3 * time.Second

var (
	ErrPoolNotExist  = errors.New("pool not exist")
	ErrGetResTimeout = errors.New("get resource time out")
)

//Resource
type Resource struct {
	resId int
}

//NewResource Simulate slow resource initialization creation
// (e.g., TCP connection, SSL symmetric key acquisition, auth authentication are time-consuming)
func NewResource(id int) *Resource {
	time.Sleep(500 * time.Millisecond)
	return &Resource{resId: id}
}

//Do Simulation resources are time consuming and random consumption is 0~400ms
func (r *Resource) Do(workId int) {
	time.Sleep(time.Duration(rand.Intn(5)) * 100 * time.Millisecond)
	log.Printf("using resource #%d finished work %d finish\n", r.resId, workId)
}

//Pool based on Go channel implementation, to avoid resource race state problem
type Pool chan *Resource

//New a resource pool of the specified size
// Resources are created concurrently to save resource initialization time
func New(size int) Pool {
	p := make(Pool, size)
	wg := new(sync.WaitGroup)
	wg.Add(size)
	for i := 0; i < size; i++ {
		go func(resId int) {
			p <- NewResource(resId)
			wg.Done()
		}(i)
	}
	wg.Wait()
	return p
}

//GetResource based on channel, resource race state is avoided and resource acquisition timeout is set for empty pool
func (p Pool) GetResource() (r *Resource, err error) {
	select {
	case r := <-p:
		return r, nil
	case <-time.After(getResMaxTime):
		return nil, ErrGetResTimeout
	}
}

//GiveBackResource returns resources to the resource pool
func (p Pool) GiveBackResource(r *Resource) error {
	if p == nil {
		return ErrPoolNotExist
	}
	p <- r
	return nil
}

// package main
package main

import (
	"github.com/tkstorm/go-design/creational/object-pool/pool"
	"log"
	"sync"
)

func main() {
	// Initialize a pool of five resources,
	// which can be adjusted to 1 or 10 to see the difference
	size := 5
	p := pool.New(size)

	// Invokes a resource to do the id job
	doWork := func(workId int, wg *sync.WaitGroup) {
		defer wg.Done()
		// Get the resource from the resource pool
		res, err := p.GetResource()
		if err != nil {
			log.Println(err)
			return
		}
		// Resources to return
		defer p.GiveBackResource(res)
		// Use resources to handle work
		res.Do(workId)
	}

	// Simulate 100 concurrent processes to get resources from the asset pool
	num := 100
	wg := new(sync.WaitGroup)
	wg.Add(num)
	for i := 0; i < num; i++ {
		go doWork(i, wg)
	}
	wg.Wait()
}

सी #

.NET बेस क्लास लाइब्रेरी में कुछ ऑब्जेक्ट हैं जो इस पैटर्न को लागू करते हैं। System.Threading.ThreadPool को आवंटित करने के लिए थ्रेड्स की पूर्वनिर्धारित संख्या के लिए कॉन्फ़िगर किया गया है। जब डेटा को वापस किया जाता हैं तो वे दूसरी गणना के लिए उपलब्ध होते हैं। इस प्रकार, थ्रेड्स के निर्माण की लागत का भुगतान किए बिना थ्रेड्स का उपयोग किया जा सकता है।

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

namespace DesignPattern.Objectpool;

// The PooledObject class is the type that is expensive or slow to instantiate,
// or that has limited availability, so is to be held in the object pool.
public class PooledObject
{
    private DateTime _createdAt = DateTime.Now;

    public DateTime CreatedAt
    {
        get { return _createdAt; }
    }

    public string TempData { get; set; }
}

// The Pool class controls access to the pooled objects. It maintains a list of available objects and a 
// collection of objects that have been obtained from the pool and are in use. The pool ensures that released objects 
// are returned to a suitable state, ready for reuse. 
public static class Pool
{
    private static List<PooledObject> _available = new List<PooledObject>();
    private static List<PooledObject> _inUse = new List<PooledObject>();

    public static PooledObject GetObject()
    {
        lock (_available)
        {
            if (_available.Count != 0)
            {
                PooledObject po = _available[0];
                _inUse.Add(po);
                _available.RemoveAt(0);
                return po;
            }
            else
            {
                PooledObject po = new PooledObject();
                _inUse.Add(po);
                return po;
            }
        }
    }

    public static void ReleaseObject(PooledObject po)
    {
        CleanUp(po);

        lock (_available)
        {
            _available.Add(po);
            _inUse.Remove(po);
        }
    }

    private static void CleanUp(PooledObject po)
    {
        po.TempData = null;
    }
}

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

जावा

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

public class PooledObject {
	public String temp1;
	public String temp2;
	public String temp3;
	
	public String getTemp1() {
		return temp1;
	}
	public void setTemp1(String temp1) {
		this.temp1 = temp1;
	}
	public String getTemp2() {
		return temp2;
	}
	public void setTemp2(String temp2) {
		this.temp2 = temp2;
	}
	public String getTemp3() {
		return temp3;
	}
	public void setTemp3(String temp3) {
		this.temp3 = temp3;
	}
}
public class PooledObjectPool {
	private static long expTime = 6000;//6 seconds
	public static HashMap<PooledObject, Long> available = new HashMap<PooledObject, Long>();
	public static HashMap<PooledObject, Long> inUse = new HashMap<PooledObject, Long>();
	
	public synchronized static PooledObject getObject() {
		long now = System.currentTimeMillis();
		if (!available.isEmpty()) {
			for (Map.Entry<PooledObject, Long> entry : available.entrySet()) {
				if (now - entry.getValue() > expTime) { //object has expired
					popElement(available);
				} else {
					PooledObject po = popElement(available, entry.getKey());
					push(inUse, po, now); 
					return po;
				}
			}
		}

		// either no PooledObject is available or each has expired, so return a new one
		return createPooledObject(now);
	}	
	
	private synchronized static PooledObject createPooledObject(long now) {
		PooledObject po = new PooledObject();
		push(inUse, po, now);
		return po;
    }

	private synchronized static void push(HashMap<PooledObject, Long> map,
			PooledObject po, long now) {
		map.put(po, now);
	}

	public static void releaseObject(PooledObject po) {
		cleanUp(po);
		available.put(po, System.currentTimeMillis());
		inUse.remove(po);
	}
	
	private static PooledObject popElement(HashMap<PooledObject, Long> map) {
		 Map.Entry<PooledObject, Long> entry = map.entrySet().iterator().next();
		 PooledObject key= entry.getKey();
		 //Long value=entry.getValue();
		 map.remove(entry.getKey());
		 return key;
	}
	
	private static PooledObject popElement(HashMap<PooledObject, Long> map, PooledObject key) {
		map.remove(key);
		return key;
	}
	
	public static void cleanUp(PooledObject po) {
		po.setTemp1(null);
		po.setTemp2(null);
		po.setTemp3(null);
	}
}

यह भी देखें

टिप्पणियाँ

  1. 1.0 1.1 Goetz, Brian (2005-09-27). "Java theory and practice: Urban performance legends, revisited". IBM. IBM developerWorks. Archived from the original on 2012-02-14. Retrieved 2021-03-15.

संदर्भ

बाहरी संबंध