खोज…


परिचय

एक समवर्ती संग्रह एक [संग्रह] [1] है जो एक ही समय में एक से अधिक थ्रेड द्वारा पहुँच की अनुमति देता है। विभिन्न धागे आमतौर पर संग्रह की सामग्री के माध्यम से पुनरावृति कर सकते हैं और तत्वों को जोड़ या हटा सकते हैं। संग्रह यह सुनिश्चित करने के लिए जिम्मेदार है कि संग्रह भ्रष्ट नहीं हुआ है। [१]: http://stackoverflow.com/documentation/java/90/collections#t=201612221936497298484

थ्रेड-सुरक्षित संग्रह

डिफ़ॉल्ट रूप से, विभिन्न संग्रह प्रकार थ्रेड-सुरक्षित नहीं हैं।

हालांकि, एक संग्रह धागा-सुरक्षित बनाने के लिए यह काफी आसान है।

List<String> threadSafeList = Collections.synchronizedList(new ArrayList<String>());
Set<String> threadSafeSet = Collections.synchronizedSet(new HashSet<String>());
Map<String, String> threadSafeMap = Collections.synchronizedMap(new HashMap<String, String>());

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

जावा एसई 5

जावा 5 में शुरू, java.util.collections में कई नए थ्रेड-सुरक्षित संग्रह हैं, जिन्हें विभिन्न Collections.synchronized विधियों की आवश्यकता नहीं है।

List<String> threadSafeList = new CopyOnWriteArrayList<String>();
Set<String> threadSafeSet = new ConcurrentHashSet<String>();
Map<String, String> threadSafeMap = new ConcurrentHashMap<String, String>();

समवर्ती संग्रह

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

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

यह वह जगह है जहाँ समवर्ती संग्रह का उपयोग किया जाता है।

जैसा कि अक्सर संग्रह में कई थोक तरीकों का आधार कार्यान्वयन होता है, जैसे कि addAll , removeAll , या संग्रह प्रतिलिपि बनाना (एक निर्माता, या अन्य माध्यमों के माध्यम से), छँटाई, ... समवर्ती संग्रह के लिए उपयोग का मामला वास्तव में बहुत बड़ा है।

उदाहरण के लिए, जावा एसई 5 java.util.concurrent.CopyOnWriteArrayList एक थ्रेड सुरक्षित और समवर्ती Lis टी कार्यान्वयन है, जो इसके जावाडॉक कहता है:

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

इसलिए, निम्न कोड सुरक्षित है:

public class ThreadSafeAndConcurrent {

public static final List<Integer> LIST = new CopyOnWriteArrayList<>();

public static void main(String[] args) throws InterruptedException {
    Thread modifier = new Thread(new ModifierRunnable());
    Thread iterator = new Thread(new IteratorRunnable());
    modifier.start();
    iterator.start();
    modifier.join();
    iterator.join();
}

public static final class ModifierRunnable implements Runnable {
    @Override
    public void run() {
        try {
            for (int i = 0; i < 50000; i++) {
                LIST.add(i);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public static final class IteratorRunnable implements Runnable {
    @Override
    public void run() {
        try {
            for (int i = 0; i < 10000; i++) {
                long total = 0;
                for(Integer inList : LIST) {
                    total += inList;
                }
                System.out.println(total);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
}

पुनरावृत्ति के संबंध में एक और समवर्ती संग्रह है ConcurrentLinkedQueue , जो बताता है:

इटरेटर कमजोर रूप से सुसंगत हैं, लौटाने वाले तत्व किसी बिंदु पर या इटरेटर के निर्माण के बाद से कतार की स्थिति को दर्शाते हैं। वे java.util.ConcurrentModificationException को नहीं फेंकते हैं, और अन्य कार्यों के साथ समवर्ती रूप से आगे बढ़ सकते हैं। इट्रेटर के निर्माण के बाद से कतार में शामिल तत्व एक बार ठीक वापस आ जाएंगे।

एक संग्रह समवर्ती है या नहीं, यह देखने के लिए एक को javadocs की जाँच करनी चाहिए। इट्रेटर द्वारा लौटाए गए इट्रेटर की विशेषताएं iterator() विधि ("तेजी से विफल", "कमजोर रूप से सुसंगत", ...) देखने के लिए सबसे महत्वपूर्ण विशेषता है।

थ्रेड सुरक्षित लेकिन गैर समवर्ती उदाहरण

उपरोक्त कोड में, LIST घोषणा को बदलकर

public static final List<Integer> LIST = Collections.synchronizedList(new ArrayList<>());

अधिकांश आधुनिक, बहु सीपीयू / कोर आर्किटेक्चर) पर अपवाद के लिए नेतृत्व कर सकते हैं।

Collections उपयोगिता विधियों से सिंक्रनाइज़ किए गए संग्रह तत्वों को जोड़ने / हटाने के लिए थ्रेड सुरक्षित हैं, लेकिन पुनरावृत्ति नहीं (जब तक कि अंतर्निहित संग्रह पहले से ही इसे पारित नहीं किया जा रहा है)।

समवर्ती हाशपा में प्रविष्टि

public class InsertIntoConcurrentHashMap
{

    public static void main(String[] args)
    {
        ConcurrentHashMap<Integer, SomeObject> concurrentHashMap = new ConcurrentHashMap<>();

        SomeObject value = new SomeObject();
        Integer key = 1;

        SomeObject previousValue = concurrentHashMap.putIfAbsent(1, value);
        if (previousValue != null)
        {
            //Then some other value was mapped to key = 1. 'value' that was passed to
            //putIfAbsent method is NOT inserted, hence, any other thread which calls
            //concurrentHashMap.get(1) would NOT receive a reference to the 'value'  
            //that your thread attempted to insert. Decide how you wish to handle             
            //this situation.
        }

       else
       {
            //'value' reference is mapped to key = 1.
       }
    }
}


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow