8

जावा गुरुओं के लिए आधारित कस्टम मानचित्र ReentrantReadWriteLock बनाम,ConcurrentHashMap को पुन: लोड

वर्तमान में हम एक HashMap<String,SomeApplicationObject> जो अक्सर पढ़ सकते हैं और कभी-कभी संशोधित और हम मुद्दों कर रहे किया जा रहा है है कि संशोधन/पुन: लोड, पढ़ें आपरेशन रिटर्न दौरान null जो स्वीकार्य नहीं है।

इसे ठीक करने के मैं निम्नलिखित विकल्प हैं:

ए का प्रयोग करें ConcurrentHashMap

कौन सा पहली पसंद लेकिन आपरेशन जो हम बात कर रहे हैं की तरह लग रहा reload() है - इसका मतलब है clear()replaceAll() द्वारा पीछा किया। तो यदि Map पोस्ट clear() और पूर्व replaceAll() पढ़ा जाता है तो यह शून्य हो जाता है जो वांछनीय नहीं है। भले ही मैं synchronize यह समस्या का समाधान नहीं करता है।

बी एक और कार्यान्वयन पर ReentrantReadWriteLock

आधारित मैं कहां से reload() ऑपरेशन से पहले अधिग्रहण Write Lock बन जाएगा बनाएँ। यह अधिक उपयुक्त लगता है लेकिन मुझे लगता है कि इसके लिए पहले से ही कुछ उपलब्ध होना चाहिए और मुझे पहिया को फिर से शुरू करने की आवश्यकता नहीं है।

सबसे अच्छा तरीका क्या है?

संपादित करें क्या कोई संग्रह पहले से ही इस सुविधा के साथ उपलब्ध है?

+0

आपके नक्शे प्रभावी रूप से अपरिवर्तनीय हैं, जो उन्हें 'अस्थिर' के माध्यम से प्रकाशन के लिए एक आदर्श लक्ष्य बनाता है। –

+0

** प्रभावी रूप से अपरिवर्तनीय ** क्षमा करें मुझे 'अपरिवर्तनीय' समझ में नहीं आता है ... क्या आप कृपया कुछ संकेत प्रदान कर सकते हैं ??? – SiB

उत्तर

4

ऐसा लगता है कि आप इस बारे में निश्चित नहीं हैं कि पीटर लॉरी के सुझावों को कैसे लागू किया जा सकता है। यह ऐसा दिखाई दे सकता:

class YourClass { 
    private volatile Map<String, SomeApplicationObject> map; 

    //constructors etc. 

    public void reload() { 
     Map<String,SomeApplicationObject> newMap = getNewValues(); 
     map = Collections.unmodifiableMap(newMap); 
    } 
} 

कोई संगामिति मुद्दों क्योंकि इस प्रकार हैं:

  • नया नक्शा एक स्थानीय चर, जो परिभाषा के द्वारा साझा नहीं है के माध्यम से बनाई गई है - getNewValues सिंक्रनाइज़ किया की जरूरत नहीं है या परमाणु
  • map को assignement परमाणु है
  • map अस्थिर है, जो गारंटी देता है कि अन्य थ्रेड परिवर्तन देखेंगे
8

चूंकि आप मानचित्र को फिर से लोड कर रहे हैं, इसलिए मैं इसे पुनः लोड पर बदल दूंगा।

आप इसे अस्थिर मानचित्र का उपयोग करके कर सकते हैं, जिसे आप अपडेट करते समय पूर्ण रूप से बदलते हैं।

+0

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

+0

पूरे मानचित्र को प्रतिस्थापित करने के लिए, आपको केवल नई प्रतिलिपि बनाने के लिए अपने क्षेत्र में पुराने अस्थिर संदर्भ में नया नक्शा असाइन करना होगा। यानी आप वास्तव में सभी को बदल रहे हैं, यहां तक ​​कि मानचित्र स्वयं ही इसकी सामग्री नहीं है। –

5

यह एक बहुतGuava's तरह Cache लगता है, हालांकि यह वास्तव में निर्भर करता है कि आप नक्शे को आबाद करने कर रहे हैं, और कैसे आप मूल्यों की गणना। (प्रकटीकरण: मैं अमरूद में योगदान देता हूं।)

असली सवाल यह है कि आप इनपुट इनपुट SomeApplicationObject की गणना कैसे कर सकते हैं या नहीं। बस क्या आप हमें बता चुके अब तक के आधार पर, यह कुछ इस तरह लग सकता है ...

LoadingCache<String, SomeApplicationObject> cache = CacheBuilder.newBuilder() 
    .build(
     new CacheLoader<String, SomeApplicationObject>() { 
     public SomeApplicationObject load(String key) throws AnyException { 
      return computeSomeApplicationObject(key); 
     } 
     }); 

फिर, जब भी आप कैश के पुनर्निर्माण के लिए करना चाहता था, तो आप सिर्फ cache.invalidateAll() कहते हैं। LoadingCache के साथ, आप cache.get(key) पर कॉल कर सकते हैं और यदि उसने पहले से ही मान की गणना नहीं की है, तो इसे पुनः संयोजित किया जाएगा। या शायद cache.invalidateAll() पर कॉल करने के बाद, आप cache.loadAll(allKeys) पर कॉल कर सकते हैं, हालांकि आपको invalidateAll और loadAll के बीच कोई प्रश्न आने पर भी एक समय में एकल तत्व लोड करने में सक्षम होना चाहिए।

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

+0

SomeAplicationObject एक ऐसी संस्था है जो डीबी से प्रीलोड किया जाता है जब एप्लिकेशन शुरू होता है और मानचित्र से हर समय पढ़ता है ... कभी-कभी सिस्टम व्यवस्थापक मानों को फिर से लोड कर सकता है। – SiB