दिलचस्प पोस्ट
एसक्यूएल बनाम एसक्यूएल उपश्रेणीयां (प्रदर्शन)? आगे की समझ सेटरेटइन इन्स्टेंस (सच) जावा प्रोग्राम से मैं पूरी तरह से स्वतंत्र प्रक्रिया कैसे लांच करूं? विंडोज में एक क्रॉन नौकरी की स्थापना दिए गए इंटरफ़ेस को लागू करने वाले सभी वर्गों को कैसे खोजें? XMLHttpRequest फ़ाइल लोड नहीं कर सकता। क्रॉस मूल अनुरोध केवल HTTP के लिए समर्थित हैं जावास्क्रिप्ट एकाधिक चाबियाँ एक बार में दबायीं छोरों के लिए नेस्टेड से बचना रिटर्निंग आईईइन्मेरेबल <T> बनाम IQueryable <T> मैं यूनिक्स में एक फ़ाइल में डुप्लिकेट लाइनों को कैसे हटा सकता हूं? सरणी के क्रमबद्धन WPF में डमी डिजाइन समय डेटा के लिए कौन से दृष्टिकोण उपलब्ध हैं? कैसे मेरी WCF सेवा अतुल्यकालिक को कॉल करने के लिए? स्क्रॉल इवेंट फायरिंग कई बार। मैं केवल इसे एक अधिकतम, आग्रह करता हूं, एक बार प्रति सेकंड आग लगाना चाहता हूं रनटाइम में एक नौ पैच / नैनपैच ड्रायवेट बनाएँ

क्या अलग-अलग कुंजी के लिए हैश-मैप धागा-सुरक्षित है?

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

वेब के समाधान से एकत्रित समाधान "क्या अलग-अलग कुंजी के लिए हैश-मैप धागा-सुरक्षित है?"

@ डॉट्सड के जवाब में वह यह कहता है:

यदि आप किसी भी तरह से एक हैशमैप बदलते हैं तो आपका कोड बस टूटा हुआ है।

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

  • अगर एक धागा put , तो एक और थ्रेड hashmap के आकार के लिए एक बासी मूल्य देख सकता है।

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

  • जब एक धागा एक चाबी के लिए put है जो कुछ अन्य धागे द्वारा उपयोग की जाने वाली कुछ कुंजी के साथ टकराता है, और बाद के थ्रेड को अपनी कुंजी के लिए put , तो बाद में हैश श्रृंखला संदर्भ की एक पुरानी प्रति दिखाई दे सकता है अराजकता फिर से शुरू हो सकती है

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

और यदि आपके पास दो धागे हैं, तो साथ में अनुरोध करना या remove , दौड़ की स्थितियों के लिए कई अवसर हैं

मैं तीन समाधानों के बारे में सोच सकता हूं:

  1. एक ConcurrentHashMap उपयोग करें
  2. एक नियमित HashMap उपयोग करें, लेकिन बाहर पर सिंक्रनाइज़; जैसे कि आदिम म्यूटक्सेज़, Lock ऑब्जेक्ट, वगैरह का उपयोग करना
  3. प्रत्येक थ्रेड के लिए एक भिन्न HashMap उपयोग करें। यदि धागे में वास्तव में चाबियों का एक पृथक सेट है, तो उन्हें एक नक्शा साझा करने के लिए कोई एल्गोरिथम परिप्रेक्ष्य (कोई ज़रूरत नहीं) की आवश्यकता होनी चाहिए। दरअसल, यदि आपके एल्गोरिदम में कुछ बिंदुओं पर मानचित्रों की चाबियाँ, मान या प्रविष्टि के चलने वाले धागे शामिल होते हैं, तो एक नक्शा को कई मानचित्रों में विभाजित करना प्रोसेसिंग के उस भाग के लिए एक महत्वपूर्ण गति प्रदान कर सकता है।

बस एक समवर्ती HashMap का उपयोग करें ConcurrentHashMap कई तालों का उपयोग करता है जो कि एक ताला होने की संभावना को कम करने के लिए हेश बाल्टी की एक श्रृंखला को कवर करता है। एक निर्विरोध लॉक प्राप्त करने पर सीमांत प्रदर्शन प्रभाव पड़ता है

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

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

हालांकि यह दृश्यता के बारे में कोई गारंटी नहीं देता है इसलिए आपको कभी-कभी बासी संघों को पुनः प्राप्त करने को स्वीकार करने के लिए तैयार रहना होगा।

यह "अभिगमन" के तहत क्या मतलब है पर निर्भर करता है यदि आप अभी पढ़ रहे हैं, तो आप " पहले-पहले " नियमों के तहत गारंटीकृत डेटा की दृश्यता के रूप में एक ही कुंजी भी पढ़ सकते हैं। इसका मतलब यह है कि HashMap को बदलना नहीं चाहिए और सभी रीडर्स (प्रारंभिक निर्माण) को पूरा करने से पहले किसी भी रीडर को HashMap तक पहुंचने से पहले पूरा करना चाहिए।

यदि आप किसी भी तरह से एक HashMap बदलते हैं तो आपका कोड बस टूटा हुआ है। @ स्टीफन सी बहुत अच्छा विवरण क्यों देता है

संपादित करें: यदि पहला मामला आपकी वास्तविक स्थिति है, तो मैं आपको Collections.unmodifiableMap() । अनमोडिफाइज़ेबल मैप Collections.unmodifiableMap() का उपयोग करने की सलाह देता हूं ताकि आपके हाशम को कभी भी बदला न जाए। ऑब्जेक्ट जो कि HashMap द्वारा इंगित किए जाते हैं, उन्हें भी बदलना नहीं चाहिए, इसलिए final कीवर्ड का उपयोग करने वाले आक्रामक आपकी सहायता कर सकते हैं।

और जैसा @ लार एंड्रेन कहते हैं, ConcurrentHashMap हैशमैप ज्यादातर मामलों में सबसे अच्छा विकल्प है।

दो धागे से उचित सिंक्रनाइज़ेशन के बिना एक हैशमार्क को संशोधित करने से आसानी से एक दौड़ की स्थिति हो सकती है।

  • जब एक put() आंतरिक तालिका का आकार बदल जाता है, तो इसमें कुछ समय लगता है और दूसरी थ्रेड पुराने तालिका में लिखना जारी रहता है।
  • दो चाबियाँ put() अलग चाबी के लिए एक ही बाल्टी के एक अद्यतन करने के लिए नेतृत्व अगर चाबियाँ 'hashcodes बराबर हैं modulo टेबल आकार (वास्तव में, हैशोड और बाल्टी इंडेक्स के बीच का संबंध अधिक जटिल है, लेकिन अभी भी टकराव हो सकते हैं।)