जावा समवर्ती मानचित्र: Difference between revisions

From Vigyanwiki
mNo edit summary
Line 21: Line 21:
=== समवर्ती हाश आलेखन ===
=== समवर्ती हाश आलेखन ===


Java.util.Map संयोजन में परिभाषित अक्रमित पहुंच के लिए, java.util.concurrent.ConcurrentHashMap Java.util.concurrent.ConcurrentMap लागू करता है। प्रणाली प्रविष्टियों की सूची के साथ हैश तालिका के लिए एक हैश पहुँच है, प्रत्येक प्रविष्टि में एक कुंजी, एक मान, हैश और एक अगला संदर्भ होता है। जावा 8 से पहले, तालिका के एक 'अनुभाग' तक पहुंच को क्रमबद्ध करने के लिए कई ताले थे। जावा 8 में, स्थानीय समकालीनता का उपयोग स्वयं सूचियों के शीर्ष पर किया जाता है, और सूचियाँ छोटे वृक्षों में परिवर्तित हो सकते हैं जब वे दुर्भाग्यपूर्ण हैश टकरावों के कारण बहुत बड़े होने की धमकी देते हैं। इसके अतिरिक्त, जावा 8 प्रारंभिक हेड्स को तालिका में रखने के लिए आशावादी रूप से तुलनात्मक -और-स्थिर प्राथमिक का उपयोग करता है, जो बहुत तीव्र है। प्रदर्शन O(n) है, लेकिन जब पुन: साझा करना आवश्यक होता है तो कभी कभी देरी हो सकती है। हैश तालिका के विस्तार के बाद, यह कभी सिकुड़ता नहीं है, संभवतः प्रविष्टियों को हटा दिए जाने के बाद मेमोरी 'लीक' हो सकती है।
Java.util.Map संयोजन में परिभाषित अक्रमित पहुंच के लिए, java.util.concurrent.ConcurrentHashMap Java.util.concurrent.ConcurrentMap लागू करता है। प्रणाली प्रविष्टियों की सूची के साथ हैश तालिका के लिए एक हैश पहुँच है, प्रत्येक प्रविष्टि में एक कुंजी, एक मान, हैश और एक अगला संदर्भ होता है। जावा 8 से पहले, तालिका के एक 'अनुभाग' तक पहुंच को क्रमबद्ध करने के लिए कई ताले थे। जावा 8 में, स्थानीय समकालीनता का उपयोग स्वयं सूचियों के शीर्ष पर किया जाता है, और सूचियाँ छोटे वृक्षों में परिवर्तित हो सकते हैं जब वे दुर्भाग्यपूर्ण हैश टकरावों के कारण बहुत बड़े होने की धमकी देते हैं। इसके अतिरिक्त, जावा 8 प्रारंभिक हेड्स को तालिका में रखने के लिए आशावादी रूप से तुलनात्मक और स्थिर प्राथमिक का उपयोग करता है, जो बहुत तीव्र है। प्रदर्शन O(n) है, लेकिन जब पुन: साझा करना आवश्यक होता है तो कभी कभी देरी हो सकती है। हैश तालिका के विस्तार के बाद, यह कभी सिकुड़ता नहीं है, संभवतः प्रविष्टियों को हटा दिए जाने के बाद मेमोरी 'लीक' हो सकती है।


=== समवर्ती  '''स्किप''' सूची आलेखन ===
=== समवर्ती  '''स्किप''' सूची आलेखन ===
Line 43: Line 43:
=== Collections.synchronizedMap() ===
=== Collections.synchronizedMap() ===


समवर्ती संशोधन समस्या का एक समाधान संग्रह में फैक्ट्री द्वारा प्रदान किए गए एक विशेष रैपर वर्ग का उपयोग कर रहा है: <code>public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)</code> जो मौजूदा गैर-सूत्रण-सुरक्षित आलेखन को आंतरिक म्यूटेक्स पर सिंक्रनाइज़ करने वाले तरीकों से लपेटता है। अन्य प्रकार के संग्रहों के लिए रैपर भी हैं। यह एक आंशिक समाधान है, क्योंकि यह अभी भी संभव है कि अंतर्निहित आलेखन को सूत्रण्स द्वारा अनजाने में एक्सेस किया जा सकता है जो अलिखित संदर्भों को रखता है या प्राप्त करता है। साथ ही, सभी संग्रह लागू करते हैं{{Javadoc:SE|package=java.lang|java/lang|Iterable}} लेकिन सिंक्रोनाइज़्ड-रैप्ड आलेखन और अन्य रैप्ड कलेक्शंस सिंक्रोनाइज़्ड इटरेटर प्रदान नहीं करते हैं, इसलिए सिंक्रोनाइज़ेशन को क्लाइंट कोड पर छोड़ दिया जाता है, जो धीमा और त्रुटि प्रवण है और सिंक्रोनाइज़्ड मैप के अन्य उपभोक्ताओं द्वारा डुप्लिकेट होने की उम्मीद करना संभव नहीं है। पुनरावृत्ति की पूरी अवधि को भी संरक्षित किया जाना चाहिए। इसके अतिरिक्त, एक नक्शा जो अलग-अलग स्थानों में दो बार लपेटा जाता है, में अलग-अलग आंतरिक म्यूटेक्स ऑब्जेक्ट होंगे, जिन पर सिंक्रनाइज़ेशन संचालित होता है, ओवरलैप की अनुमति देता है। प्रतिनिधिमंडल एक प्रदर्शन रिड्यूसर है, लेकिन आधुनिक जस्ट-इन-टाइम कंपाइलर अक्सर भारी रूप से इनलाइन होते हैं, जो प्रदर्शन में कमी को सीमित करते हैं। यहां बताया गया है कि रैपिंग रैपर के अंदर कैसे काम करता है - म्यूटेक्स सिर्फ एक अंतिम वस्तु है और एम अंतिम लपेटा हुआ नक्शा है:
समवर्ती संशोधन समस्या का एक समाधान संग्रह में कारख़ाने द्वारा प्रदान किए गए एक विशेष कवच वर्ग का उपयोग कर रहा है: <code>public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)</code> जो उपस्थित गैर-सूत्रण-सुरक्षित आलेखन को आंतरिक म्यूटेक्स पर समकालीन करने वाले तरीकों से लपेटता है। अन्य प्रकार के संग्रहों के लिए कवच भी हैं। यह एक आंशिक समाधान है, क्योंकि यह अभी भी संभव है कि अंतर्निहित आलेखन को सूत्रण द्वारा अनजाने में एक्सेस किया जा सकता है जो अलिखित संदर्भों को रखता है या प्राप्त करता है। साथ ही, सभी संग्रह लागू करते हैं{{Javadoc:SE|package=java.lang|java/lang|Iterable}} लेकिन समकालीन-कवच आलेखन और अन्य कवच संग्रहण समकालीन संयोजन प्रदान नहीं करते हैं, इसलिए समकालीन को क्लाइंट कोड पर छोड़ दिया जाता है, जो धीमा और त्रुटि प्रवण है और समकालीन आलेखन के अन्य उपभोक्ताओं द्वारा प्रतिरूप होने की उम्मीद करना संभव नहीं है। पुनरावृत्ति की पूरी अवधि को भी संरक्षित किया जाना चाहिए। इसके अतिरिक्त, एक नक्शा जो अलग-अलग स्थानों में दो बार लपेटा जाता है, में अलग-अलग आंतरिक म्यूटेक्स ऑब्जेक्ट होंगे, जिन पर समकालीन संचालित होता है, ओवरलैप की अनुमति देता है। प्रतिनिधिमंडल एक प्रदर्शन क्षीण होना है, लेकिन आधुनिक जस्ट-इन-टाइम कंपाइलर अक्सर भारी रूप से इनलाइन होते हैं, जो प्रदर्शन में कमी को सीमित करते हैं। यहां बताया गया है कि रैपिंग रैपर के अंदर कैसे काम करता है - म्यूटेक्स सिर्फ एक अंतिम वस्तु है और एम अंतिम लपेटा हुआ नक्शा है:


<syntaxhighlight lang="java">
<syntaxhighlight lang="java">

Revision as of 20:31, 14 June 2023

जावा प्रोग्रामिंग भाषा का जावा संग्रह ढांचा संस्करण 1.5 और बाद में वास्तविक नियमित एकल सूत्रण आलेखन को परिभाषित और लागू करता है, और नए सूत्रण-सुरक्षित java.util.concurrent.ConcurrentMap अन्य संयोजन और समवर्ती संयोजन के बीच आलेखन भी लागू करते है।

जावा 1.6 में,java.util.NavigableMap संयोजन जोड़ा गया था और java.util.SortedMap तक विस्तार किया गया था।

और यहjava.util.concurrent.ConcurrentNavigableMap संयोजन को उपसंयोजन के रूप में जोड़ा गया था।

जावा आलेखन संयोजन

संस्करण 1.8 आलेखन संयोजन आरेख का आकार नीचे है। समूह को संबंधित आलेखनों के उप-स्तिथियों के रूप में माना जा सकता है जिसमें मान हमेशा एक विशेष स्थिरांक होते हैं जिन्हें उपेक्षित किया जा सकता है, हालांकि समूह एपीआई संबंधित लेकिन अलग-अलग नामित विधियों का उपयोग करता है। नीचे java.util.concurrent.ConcurrentNavigableMap है, जो एक एकाधिक-वंशानुक्रम है।

कार्यान्वयन

समवर्ती हाश आलेखन

Java.util.Map संयोजन में परिभाषित अक्रमित पहुंच के लिए, java.util.concurrent.ConcurrentHashMap Java.util.concurrent.ConcurrentMap लागू करता है। प्रणाली प्रविष्टियों की सूची के साथ हैश तालिका के लिए एक हैश पहुँच है, प्रत्येक प्रविष्टि में एक कुंजी, एक मान, हैश और एक अगला संदर्भ होता है। जावा 8 से पहले, तालिका के एक 'अनुभाग' तक पहुंच को क्रमबद्ध करने के लिए कई ताले थे। जावा 8 में, स्थानीय समकालीनता का उपयोग स्वयं सूचियों के शीर्ष पर किया जाता है, और सूचियाँ छोटे वृक्षों में परिवर्तित हो सकते हैं जब वे दुर्भाग्यपूर्ण हैश टकरावों के कारण बहुत बड़े होने की धमकी देते हैं। इसके अतिरिक्त, जावा 8 प्रारंभिक हेड्स को तालिका में रखने के लिए आशावादी रूप से तुलनात्मक और स्थिर प्राथमिक का उपयोग करता है, जो बहुत तीव्र है। प्रदर्शन O(n) है, लेकिन जब पुन: साझा करना आवश्यक होता है तो कभी कभी देरी हो सकती है। हैश तालिका के विस्तार के बाद, यह कभी सिकुड़ता नहीं है, संभवतः प्रविष्टियों को हटा दिए जाने के बाद मेमोरी 'लीक' हो सकती है।

समवर्ती स्किप सूची आलेखन

Java.util.NavigableMap संयोजन द्वारा परिभाषित आदेशित पहुँच के लिए, Java.util.concurrent.ConcurrentSkipListMap जावा 1.6 में जोड़ा गया था, और java.util.concurrent.ConcurrentMap और java.util.concurrent.ConcurrentNavigableMap को लागू करता है। प्रदर्शन O(log(n)) है और यह एक स्किप सूची है जो वृक्ष बनाने के लिए अवरोध मुक्त तकनीकों का उपयोग करती है।

सीटीआरई

  • Ctrie एक त्रि-आधारित अवरोध मुक्त वृक्ष है।

समवर्ती संशोधन समस्या

जावा 1.5 java.util.concurrent पैकेज द्वारा हल की गई एक समस्या समवर्ती संशोधन की है। इसके द्वारा प्रदान की जाने वाली संग्रह श्रेणियों को विभिन्न सूत्रण द्वारा मज़बूती से उपयोग किया जा सकता है।

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

संशोधन काउंटर

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

Collections.synchronizedMap()

समवर्ती संशोधन समस्या का एक समाधान संग्रह में कारख़ाने द्वारा प्रदान किए गए एक विशेष कवच वर्ग का उपयोग कर रहा है: public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) जो उपस्थित गैर-सूत्रण-सुरक्षित आलेखन को आंतरिक म्यूटेक्स पर समकालीन करने वाले तरीकों से लपेटता है। अन्य प्रकार के संग्रहों के लिए कवच भी हैं। यह एक आंशिक समाधान है, क्योंकि यह अभी भी संभव है कि अंतर्निहित आलेखन को सूत्रण द्वारा अनजाने में एक्सेस किया जा सकता है जो अलिखित संदर्भों को रखता है या प्राप्त करता है। साथ ही, सभी संग्रह लागू करते हैंjava.lang.Iterable लेकिन समकालीन-कवच आलेखन और अन्य कवच संग्रहण समकालीन संयोजन प्रदान नहीं करते हैं, इसलिए समकालीन को क्लाइंट कोड पर छोड़ दिया जाता है, जो धीमा और त्रुटि प्रवण है और समकालीन आलेखन के अन्य उपभोक्ताओं द्वारा प्रतिरूप होने की उम्मीद करना संभव नहीं है। पुनरावृत्ति की पूरी अवधि को भी संरक्षित किया जाना चाहिए। इसके अतिरिक्त, एक नक्शा जो अलग-अलग स्थानों में दो बार लपेटा जाता है, में अलग-अलग आंतरिक म्यूटेक्स ऑब्जेक्ट होंगे, जिन पर समकालीन संचालित होता है, ओवरलैप की अनुमति देता है। प्रतिनिधिमंडल एक प्रदर्शन क्षीण होना है, लेकिन आधुनिक जस्ट-इन-टाइम कंपाइलर अक्सर भारी रूप से इनलाइन होते हैं, जो प्रदर्शन में कमी को सीमित करते हैं। यहां बताया गया है कि रैपिंग रैपर के अंदर कैसे काम करता है - म्यूटेक्स सिर्फ एक अंतिम वस्तु है और एम अंतिम लपेटा हुआ नक्शा है:

    public V put(K key, V value) {
        synchronized (mutex) { return m.put(key, value); }
    }

पुनरावृत्ति के तुल्यकालन की अनुशंसा निम्नानुसार की जाती है, हालाँकि, यह आंतरिक म्यूटेक्स के बजाय आवरण पर तुल्यकालन करता है, ओवरलैप की अनुमति देता है:[1]

    Map<String, String> wrappedMap = Collections.synchronizedMap(map);
          ...
    synchronized (wrappedMap) {
        for (String s : wrappedMap.keySet()) {
            // some possibly long operation executed possibly 
            // many times, delaying all other accesses
        }
    }


मूल तुल्यकालन

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

    Map<String, String> map = new HashMap<String, String>();
    ...
    // Thread A
    // Use the map itself as the lock. Any agreed object can be used instead.
    synchronized(map) {
       map.put("key","value");
    }
    ..
    // Thread B
    synchronized (map) {
        String result = map.get("key");
         ...
     }
    ...
    // Thread C
    synchronized (map) {
        for (Entry<String, String> s : map.entrySet()) {
            /*
             * Some possibly slow operation, delaying all other supposedly fast operations. 
             * Synchronization on individual iterations is not possible.
             */ 
            ...
        }
    }


ReentrantReadWriteLock

Java.util.concurrent.ReentrantReadWriteLock का उपयोग करने वाला कोड मूल सिंक्रनाइज़ेशन के समान है। हालांकि, सुरक्षा के लिए, ताले को कोशिश/आखिरकार ब्लॉक में इस्तेमाल किया जाना चाहिए ताकि प्रारंभिक निकास जैसे अपवाद फेंकना या तोड़ना/जारी रखना अनलॉक से गुजरना सुनिश्चित हो। यह तकनीक सिंक्रोनाइज़ेशन का उपयोग करने से बेहतर है क्योंकि पढ़ना एक दूसरे को ओवरलैप कर सकता है, पढ़ने के संबंध में लिखने को प्राथमिकता देने का निर्णय लेने में एक नया मुद्दा है। सादगी के लिए इसके बजाय java.util.concurrent.ReentrantLock का उपयोग किया जा सकता है, जो पढ़ने/लिखने में कोई अंतर नहीं करता है। तुल्यकालन की तुलना में तालों पर अधिक संचालन संभव है, जैसे tryLock() और tryLock(long timeout, TimeUnit unit).

    final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    final ReadLock readLock = lock.readLock();
    final WriteLock writeLock = lock.writeLock();
    ..
    // Thread A
    try {
        writeLock.lock();
        map.put("key","value");
        ...
    } finally {
        writeLock.unlock();
    }
    ...
    // Thread B
    try {
        readLock.lock();
        String s = map.get("key");
        ..
    } finally {
        readLock.unlock();
    }
     // Thread C
    try {
        readLock.lock();
        for (Entry<String, String> s : map.entrySet()) {
            /*
             * Some possibly slow operation, delaying all other supposedly fast operations. 
             * Synchronization on individual iterations is not possible.
             */ 
            ...
        }
    } finally {
        readLock.unlock();
    }


काफिले

म्युचुअल एक्सक्लूज़न में लॉक काफिले की समस्या है, जिसमें सूत्रण्स लॉक पर ढेर हो सकते हैं, जिससे JVM को वेटर्स की महंगी कतार बनाए रखने और वेटिंग सूत्रण्स को 'पार्क' करने की आवश्यकता होती है। किसी सूत्रण को पार्क और अनपार्क करना महंगा होता है, और धीमा संदर्भ स्विच हो सकता है। कॉन्टेक्स्ट स्विच को माइक्रोसेकंड से मिलीसेकंड तक की आवश्यकता होती है, जबकि आलेखन के अपने मूल संचालन सामान्य रूप से नैनोसेकंड लेते हैं। विवाद बढ़ने पर प्रदर्शन एकल सूत्रण्स के थ्रूपुट के एक छोटे से अंश तक गिर सकता है। जब लॉक के लिए कोई या कम विवाद नहीं होता है, हालांकि, लॉक के विवाद परीक्षण को छोड़कर प्रदर्शन पर बहुत कम प्रभाव पड़ता है। आधुनिक जेवीएम अधिकांश लॉक कोड को इनलाइन करेंगे, इसे केवल कुछ निर्देशों तक कम कर देंगे, नो-कंटेनमेंट केस को बहुत तेज रखेंगे। नेटिव सिंक्रोनाइज़ेशन या java.util.concurrent.ReentrantReadWriteLock जैसी रीएन्ट्रेंट तकनीकों में रीएन्ट्रेंसी डेप्थ के रखरखाव में अतिरिक्त प्रदर्शन-कम करने वाला सामान होता है, जो नो-कंटेनमेंट केस को भी प्रभावित करता है। आधुनिक जेवीएमएस के साथ कॉन्वॉय की समस्या कम होती दिख रही है, लेकिन इसे धीमी संदर्भ स्विचिंग से छिपाया जा सकता है: इस मामले में, विलंबता बढ़ेगी, लेकिन थ्रूपुट स्वीकार्य रहेगा। सैकड़ों सूत्रण्स के साथ, 10ms का संदर्भ स्विच समय सेकंड में विलंबता पैदा करता है।

एकाधिक कोर

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

आरेख इंगित करता है कि एक नियमित हैश मैप (बैंगनी) लपेटकर संग्रह.सिंक्रनाइज़ मैप () का उपयोग करके सिंक्रनाइज़ करना समवर्ती हैश मैप (लाल) के साथ-साथ स्केल नहीं कर सकता है। अन्य ऑर्डर किए गए ConcurrentNavigableMaps AirConcurrentMap (नीला) और ConcurrentSkipListMap (CSLM हरा) हैं। (फ्लैट स्पॉट नर्सरी से बड़े टेबल बनाने के लिए नए सिरे से हो सकते हैं, और ConcurrentHashMap अधिक जगह लेता है। ध्यान दें कि y अक्ष को 'पुट्स K' कहना चाहिए। सिस्टम 8-कोर i7 2.5 GHz है, GC को रोकने के लिए -Xms5000m के साथ)। जीसी और जेवीएम प्रक्रिया के विस्तार से वक्र काफी बदल जाते हैं, और कुछ आंतरिक लॉक-फ्री तकनीकें विवाद पर कचरा उत्पन्न करती हैं।

केवल आदेशित मानचित्र स्केलिंग कर रहे हैं, और सिंक्रनाइज़ मानचित्र वापस गिर रहा है सिंक्रोनाइज़्ड मैप वापस स्केल किए गए ऑर्डर किए गए मैप्स के समान हो गया है

पूर्वानुमेय विलंबता

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

कमजोर संगति

Java.util.concurrency संकुल समवर्ती संशोधन समस्या, काफिले की समस्या, पूर्वानुमेय विलंबता समस्या और बहु-कोर समस्या के समाधान में एक वास्तुशिल्प विकल्प शामिल है जिसे कमजोर स्थिरता कहा जाता है। इस विकल्प का अर्थ है कि रीड्स जैसे गेट () अपडेट होने पर भी ब्लॉक नहीं होगा, और यह अपडेट को खुद के साथ और रीड्स के साथ ओवरलैप करने के लिए भी स्वीकार्य है। कमजोर संगति, उदाहरण के लिए, समवर्ती आलेखन की सामग्री को एकल सूत्रण द्वारा पुनरावृत्ति के दौरान बदलने की अनुमति देती है। Iterators को एक समय में एक सूत्रण द्वारा उपयोग करने के लिए डिज़ाइन किया गया है। इसलिए, उदाहरण के लिए, एक आलेखन जिसमें दो प्रविष्टियाँ हैं जो अंतर-निर्भर हैं, एक पाठक सूत्रण द्वारा किसी अन्य सूत्रण द्वारा संशोधन के दौरान असंगत तरीके से देखा जा सकता है। एक अद्यतन जो एक प्रविष्टि (k1,v) की कुंजी को एक प्रविष्टि (k2,v) में बदलने के लिए माना जाता है, परमाणु रूप से एक हटाने (k1) और फिर एक पुट (k2, v) करने की आवश्यकता होगी, जबकि एक पुनरावृत्ति छूट सकती है प्रवेश या इसे दो स्थानों पर देखें। पुनर्प्राप्ति किसी दी गई कुंजी के लिए मान लौटाती है जो उस कुंजी के लिए नवीनतम पिछले पूर्ण अद्यतन को दर्शाती है। इस प्रकार एक 'होता है-पहले' संबंध है।

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

समवर्ती आलेखन 1.5 तरीके

समवर्ती आलेखन द्वारा प्रदान किए गए कुछ ऑपरेशन हैं जो आलेखन में नहीं हैं - जो इसे विस्तारित करता है - संशोधनों की परमाणुता की अनुमति देने के लिए। प्रतिस्थापन (के, वी 1, वी 2) के द्वारा पहचानी गई प्रविष्टि में वी 1 के अस्तित्व के लिए परीक्षण करेगा और केवल अगर पाया जाता है, तो वी 1 को परमाणु रूप से वी 2 द्वारा प्रतिस्थापित किया जाता है। नया प्रतिस्थापन (के, वी) केवल एक पुट (के, वी) करेगा यदि के पहले से ही आलेखन में है। साथ ही, putIfAbsent(k,v) केवल एक put(k,v) करेगा यदि k पहले से आलेखन में नहीं है, और निकालें(k, v) केवल v के लिए प्रविष्टि को हटा देगा यदि v मौजूद है। कुछ बहु-सूत्रणेड उपयोग मामलों के लिए यह परमाणु महत्वपूर्ण हो सकता है, लेकिन यह कमजोर-स्थिरता बाधा से संबंधित नहीं है।

समवर्ती आलेखनों के लिए, निम्नलिखित परमाणु हैं।

m.putIfAbsent(k, v) परमाणु है लेकिन इसके समतुल्य है:

    if (k == null || v == null)
        throw new NullPointerException();
    if (!m.containsKey(k)) {
        return m.put(k, v);
    } else {
        return m.get(k);
    }

एम रिप्लेस (के, वी) परमाणु है लेकिन इसके बराबर है:

    if (k == null || v == null)
        throw new NullPointerException();
    if (m.containsKey(k)) {
        return m.put(k, v);
    } else {
        return null;
    }

m.replace(k, v1, v2) परमाणु है लेकिन इसके समतुल्य है:

    if (k == null || v1 == null || v2 == null)
        throw new NullPointerException();
    if (m.containsKey(k) && Objects.equals(m.get(k), v1)) {
        m.put(k, v2);
        return true;
    } else
        return false;
    }

m.remove(k, v) परमाणु है लेकिन इसके बराबर है:

    // if Map does not support null keys or values (apparently independently)
    if (k == null || v == null)
        throw new NullPointerException();
    if (m.containsKey(k) && Objects.equals(m.get(k), v)) {
        m.remove(k);
        return true;
    } else
       return false;
    }


समवर्ती आलेखन 1.8 विधियाँ

क्योंकि आलेखन और समवर्ती आलेखन संयोजन हैं, कार्यान्वयन को तोड़े बिना उनमें नए तरीके नहीं जोड़े जा सकते। हालाँकि, जावा 1.8 ने डिफ़ॉल्ट संयोजन कार्यान्वयन की क्षमता को जोड़ा और यह कुछ नए तरीकों getOrDefault(Object, V), forEach(BiConsumer), replaceAll(BiFunction), ComputeIfAbsent(K, Function), ComputeIfPresent(K, BiFunction), कंप्यूट(K, BiFunction) के आलेखन संयोजन डिफ़ॉल्ट कार्यान्वयन में जोड़ा गया। , और मर्ज (के, वी, बायफंक्शन)। आलेखन में डिफ़ॉल्ट कार्यान्वयन परमाणुता की गारंटी नहीं देता है, लेकिन समवर्ती आलेखन ओवरराइडिंग डिफ़ॉल्ट में ये परमाणुता प्राप्त करने के लिए लॉक मुक्त तकनीकों का उपयोग करते हैं, और मौजूदा समवर्ती आलेखन कार्यान्वयन स्वचालित रूप से परमाणु होंगे। कंक्रीट कक्षाओं में लॉक-फ्री तकनीक ओवरराइड की तुलना में धीमी हो सकती है, इसलिए ठोस वर्ग उन्हें परमाणु रूप से लागू करने या न करने और समवर्ती गुणों को दस्तावेज करने का विकल्प चुन सकते हैं।

ताला मुक्त परमाणुता

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

    static final long C = 10;
    void atomicMultiply(ConcurrentMap<Long, Long> map, Long key) {
        for (;;) {
            Long oldValue = map.get(key);
            // Assuming oldValue is not null. This is the 'payload' operation, and should not have side-effects due to possible re-calculation on conflict
            Long newValue = oldValue * C;
            if (map.replace(key, oldValue, newValue))
                break;
        }
    }

putIfAbsent(k, v) तब भी उपयोगी होता है जब कुंजी के लिए प्रविष्टि को अनुपस्थित रहने की अनुमति दी जाती है। यह उदाहरण जावा 8 कंप्यूट () के साथ लागू किया जा सकता है, लेकिन यह समग्र लॉक-फ्री पैटर्न दिखाता है, जो अधिक सामान्य है। प्रतिस्थापन (के, वी 1, वी 2) शून्य पैरामीटर स्वीकार नहीं करता है, इसलिए कभी-कभी उनका संयोजन आवश्यक होता है। दूसरे शब्दों में, यदि v1 शून्य है, तो putIfAbsent(k, v2) लागू किया जाता है, अन्यथा प्रतिस्थापित करें (k,v1,v2) लागू किया जाता है।

    void atomicMultiplyNullable(ConcurrentMap<Long, Long> map, Long key) {
        for (;;) {
            Long oldValue = map.get(key);
            // This is the 'payload' operation, and should not have side-effects due to possible re-calculation on conflict
            Long newValue = oldValue == null ? INITIAL_VALUE : oldValue * C;
            if (replaceNullable(map, key, oldValue, newValue))
                break;
        }
    }
    ...
    static boolean replaceNullable(ConcurrentMap<Long, Long> map, Long key, Long v1, Long v2) {
        return v1 == null ? map.putIfAbsent(key, v2) == null : map.replace(key, v1, v2);
    }

इतिहास

जावा संग्रह ढांचे को मुख्य रूप से जोशुआ बलोच द्वारा डिजाइन और विकसित किया गया था, और इसे J2SE 1.2|JDK 1.2 में पेश किया गया था।[2] मूल संगामिति वर्ग डौग ली से आया था [3] संग्रह पैकेज।

यह भी देखें

संदर्भ

  1. "java.util.Collections.synchronizedMap". Java / Java SE / 11 / API / java.base. Oracle Help Center. September 19, 2018. Retrieved 2020-07-17.
  2. Vanhelsuwé, Laurence (January 1, 1999). "The battle of the container frameworks: which should you use?". JavaWorld. Retrieved 2020-07-17.
  3. Lea, Doug. "Overview of package util.concurrent Release 1.3.4". Retrieved 2011-01-01.
  • Goetz, Brian; Joshua Bloch; Joseph Bowbeer; Doug Lea; David Holmes; Tim Peierls (2006). Java Concurrency in Practice. Addison Wesley. ISBN 0-321-34960-1. OL 25208908M.
  • Lea, Doug (1999). Concurrent Programming in Java: Design Principles and Patterns. Addison Wesley. ISBN 0-201-31009-0. OL 55044M.


बाहरी संबंध