Java में ConcurrentHashMap?




(4)

1.ConcurrentHashMap थ्रेड-सुरक्षित है जो कि एक बार में सिंगल थ्रेड द्वारा एक्सेस किया जा सकता है।

2.ConcurrentHashMap मैप के निश्चित भाग पर सिंक्रनाइज़ या लॉक करता है। ConcurrentHashMap के प्रदर्शन का अनुकूलन करने के लिए, मैप को अलग-अलग विभाजनों में विभाजित किया गया है, जो कि कंजेंसी के स्तर पर निर्भर करता है। ताकि हमें पूरी Map Object को सिंक्रोनाइज़ करने की जरूरत न पड़े।

3.Default concurrency level 16 है, तदनुसार मैप को 16 भाग में विभाजित किया गया है और प्रत्येक भाग को एक अलग लॉक से नियंत्रित किया गया है जिसका अर्थ है कि 16 थ्रेड संचालित हो सकते हैं।

4.ConcurrentHashMap NULL मानों की अनुमति नहीं देता है। तो ConcurrentHashMap में कुंजी शून्य नहीं हो सकती है।

Java में ConcurrentHashMap का उपयोग क्या है? इसके क्या लाभ हैं? यह कैसे काम करता है? नमूना कोड भी उपयोगी होगा।


इसका उपयोग संस्मरण के लिए किया जा सकता है:

import java.util.concurrent.ConcurrentHashMap;
public static Function<Integer, Integer> fib = (n) -> {
  Map<Integer, Integer> cache = new ConcurrentHashMap<>();
  if (n == 0 || n == 1) return n;
  return cache.computeIfAbsent(n, (key) -> HelloWorld.fib.apply(n - 2) + HelloWorld.fib.apply(n - 1));
};

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

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

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

सबसे आम उपयोग जो मुझे पता है कि ऐप सर्वर के वातावरण में अपरिवर्तनीय व्युत्पन्न जानकारी को कैशिंग करने में है, जहां कई धागे एक ही चीज़ तक पहुंच सकते हैं, और यह वास्तव में कोई फर्क नहीं पड़ता है यदि दो एक ही कैश मान की गणना करते हैं और दो बार डालते हैं क्योंकि वे इंटरलेव करते हैं , आदि (उदाहरण के लिए, इसका उपयोग बड़े पैमाने पर स्प्रिंग वेबएमवीसी फ्रेमवर्क के अंदर किया जाता है, जो URL से हैंडलर विधियों की मैपिंग की तरह रनटाइम-व्युत्पन्न कॉन्फिगरेशन को पकड़ता है।)


ConcurrentHashMap नक्शे में समवर्ती पहुंच की अनुमति देता है। हैशटेबल्स भी मानचित्र के लिए सिंक्रनाइज़ एक्सेस प्रदान करता है, लेकिन आपका पूरा नक्शा किसी भी ऑपरेशन को करने के लिए बंद है।

ConcurrentHashMap के पीछे तर्क यह है कि your entire table is not getting locked , लेकिन केवल भाग [ segments ] है। प्रत्येक खंड अपने हैशटेबल का प्रबंधन करता है। लॉकिंग केवल अपडेट के लिए लागू की जाती है। पुनर्प्राप्ति के मामले में, यह पूर्ण सहमति देता है।

मान लीजिए कि चार सूत्र समवर्ती रूप से एक मानचित्र पर काम कर रहे हैं जिसकी क्षमता 32 है, तालिका को चार खंडों में विभाजित किया गया है, जहां प्रत्येक खंड क्षमता की हैश तालिका का प्रबंधन करता है। संग्रह डिफ़ॉल्ट रूप से 16 खंडों की एक सूची रखता है, जिनमें से प्रत्येक का उपयोग मानचित्र के एक बाल्टी की रक्षा (या लॉक करने) के लिए किया जाता है।

इसका प्रभावी रूप से मतलब है कि 16 धागे एक ही समय में संग्रह को संशोधित कर सकते हैं। वैकल्पिक संगामिति के निर्माण तर्क का उपयोग करके संगामिति के इस स्तर को बढ़ाया जा सकता है।

public ConcurrentHashMap(int initialCapacity,
                         float loadFactor, int concurrencyLevel)

जैसा कि अन्य उत्तर में कहा गया है, समवर्ती putIfAbsent() नई विधि putIfAbsent() प्रदान करता है जो कुंजी को छोड़कर यदि मूल्य मौजूद है तो इसे ओवरराइड नहीं किया जाएगा।

private static Map<String,String> aMap =new ConcurrentHashMap<String,String>();

if(!aMap.contains("key"))
   aMap.put("key","value");

नई विधि भी तेज है क्योंकि यह ऊपर की तरह double traversing से बचा जाता है। contains विधि में सेगमेंट का पता लगाना है और कुंजी को खोजने के लिए तालिका को पुनरावृत्त करना है और फिर से विधि को बाल्टी को पीछे करना है और कुंजी को लगाना है।







concurrenthashmap