2010-04-23 17 views
10

मैं एक बहुप्रचारित आर्किटेक्चर के लिए एक समवर्ती LinkedHashMap बनाने की कोशिश कर रहा हूं।एक समवर्ती LinkedHashMap लागू करना

यदि मैं Collections#synchronizedMap() का उपयोग करता हूं, तो मुझे पुनरावृत्ति के लिए सिंक्रनाइज़ किए गए ब्लॉक का उपयोग करना होगा। इस कार्यान्वयन से तत्वों के क्रमिक जोड़ों का कारण बन जाएगा।

यदि मैं ConcurrentSkipListMap का उपयोग करता हूं तो Comparator को अनुक्रमिक रूप से संग्रहीत करने के लिए कोई तरीका है, जैसा कि लिंक्ड लिस्ट या कतार में संग्रहीत है।

मैं तीसरे पक्ष के पैकेज के बजाय जावा का निर्माण करना चाहता हूं।

संपादित करें:

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

पुनरावृत्त करते समय, LinkedHashMap को नई प्रविष्टियों के साथ जोड़ा जा सकता है, या हटा दिया जा सकता है। लेकिन पुनरावृत्ति अनुक्रम होना चाहिए जिसमें प्रविष्टियां शामिल की गई थीं।

मैं समझता हूं कि Collections#synchronizedMap() का उपयोग करके, पुनरावृत्ति के लिए एक सिंक्रनाइज़ ब्लॉक लागू किया जाना चाहिए, लेकिन नक्शा संशोधित किया जा सकता है (प्रविष्टियों को जोड़ा/हटाया जा सकता है) जबकि इसे पुनरावृत्त किया जा रहा है।

+0

आप किस गेटर/सेटर के बारे में बात कर रहे हैं? आप "अनुक्रमिक रूप से स्टोर" करने का प्रयास कर रहे हैं? कृपया अधिक जानकारी दें - यह समझना मुश्किल है कि आप वास्तव में इस समय क्या करने की कोशिश कर रहे हैं। –

+0

आप क्रमशः स्टोर करने की कोशिश कर रहे हैं? यदि आपकी चाबियों का एक निश्चित आदेश है तो आप एक तुलनात्मक लिखने में सक्षम होना चाहिए। शायद आपको अपने मानचित्र में चाबियों और आप उन्हें कैसे आदेश देना चाहते हैं, के बारे में अधिक जानकारी प्रदान करनी चाहिए। –

उत्तर

1

Collections#synchronizedMap() का उपयोग करें।

मेरी धारणा के अनुसार, यदि मैं Collections.synchronizedMap() का उपयोग करता हूं, तो मुझे गेटर/सेटर के लिए सिंक्रनाइज़ किए गए ब्लॉक का उपयोग करना होगा।

यह सच नहीं है। आपको केवल किसी भी दृश्य (कीसेट, मान, एंट्रीसेट) पर पुनरावृत्ति को सिंक्रनाइज़ करने की आवश्यकता है। Abovelinked एपीआई दस्तावेज भी देखें।

+0

यदि मानचित्र पुनरावृत्त किया जा रहा है, तो क्या अन्य थ्रेड के लिए मानचित्र से तत्व जोड़ने या निकालना संभव होगा? – Nilesh

+0

क्या यह कार्यान्वयन – Nilesh

+0

तत्वों के अनुक्रमिक जोड़ के लिए नेतृत्व करेगा 1) यदि आप प्रलेखन के अनुसार पुनरावृत्ति को सिंक्रनाइज़ नहीं करते हैं (क्या आपने लिंक को वैसे भी क्लिक किया है?)। यह सिंक्रनाइज़ेशन का पूरा बिंदु है। 2) हां, जोड़ पहले से ही आंतरिक रूप से सिंक्रनाइज़ किया गया है, यह भी आपका पूरा इरादा है, है ना? – BalusC

2

यदि आप सिंक्रनाइज़ किए गए मैप का उपयोग करते हैं, तो आपको पुनरावृत्ति को छोड़कर, बाहरी रूप से सिंक्रनाइज़ करने की आवश्यकता नहीं है। यदि आपको मानचित्र के ऑर्डर को सुरक्षित रखने की आवश्यकता है, तो आपको सॉर्टेड मैप का उपयोग करना चाहिए। आप ConcurrentSkipListMap का उपयोग कर सकते हैं, जो थ्रेड-सुरक्षित है, या सिंक्रनाइज़ सॉर्टेड मैप के साथ संयोजन में एक और सॉर्टेड मैप।

2

LinkedHashMap में एक हैशटेबल सूची हैशटेबल के माध्यम से चल रही है। एक फीफो केवल लिखित (सम्मिलन या हटाने) पर लिंक को बदल देता है। यह एक संस्करण को काफी सरल बनाता है।

  1. केवल सम्मिलन आदेश के साथ एलएचएम लिखें।
  2. हैशटेबल के रूप में एक ConcurrentHashMap पर स्विच करें।
  3. लॉक के साथ #put()/#putIfAbsent()/#remove() को सुरक्षित रखें।
  4. "अगला" फ़ील्ड अस्थिर बनाएं।

पुनरावृत्ति पर, कोई भी लॉक आवश्यक नहीं है क्योंकि आप सुरक्षित रूप से "अगले" फ़ील्ड का पालन कर सकते हैं। #get() पर सीएचएम को सिर्फ प्रतिनिधि द्वारा रीड लॉक-फ्री हो सकता है।

+0

कोई अपराध नहीं, लेकिन जब लोग इस तरह बात करते हैं तो मुझे इससे नफरत है। मुझे पता है कि एक दोगुनी जुड़ी सूची क्या है। मुझे पता है कि हैशटेबल क्या है। लेकिन एक हैशटेबल के माध्यम से चल रही एक डबल लिंक्ड सूची का मतलब क्या है? – Pacerier

+1

हां, इसकी व्याख्या करना और कल्पना करना मुश्किल है। यह [प्रस्तुति] देखें (http://concurrentlinkedhashmap.googlecode.com/files/ConcurrentCachingAtGoogle.pdf) जहां मैंने इसे आज़माया। विचार यह है कि एक लिंक्ड सूची ऑर्डरिंग को बनाए रखती है और ओ (एन) की आवश्यकता होती है। एक हैशटेबल अनियंत्रित है और ओ (1) समय में एक प्रविष्टि पाता है। संयोजन यह है कि हैश-टेबल प्रविष्टि में सूची पॉइंटर्स हैं, इसलिए सूची में एक प्रविष्टि का आदेश दिया गया है। सूची में प्रविष्टियों को जोड़ा जा सकता है (एफआईएफओ ऑर्डर), सिर/पूंछ (एलआरयू ऑर्डर) में ले जाया गया, और ओ (1) समय (बेदखल) में हटा दिया गया। यह सस्ती रूप से एक प्रविष्टि या पहुंच आदेश मानचित्र प्रदान करता है। –

+1

यह सच नहीं है कि अगर मैं अपना 'हैश मैप' सॉर्ट करता हूं, तो यह प्रभावी रूप से "ऑर्डर" हैशैप बन जाएगा, जो मूल रूप से 'लिंक्ड हैशैप' के उद्देश्य को हरा देता है? – Pacerier

1

अब तक, मेरी परियोजना अपाचे संग्रह से LRUMap का उपयोग करती है लेकिन यह SequencedHashMap पर आधारित है। संग्रह ListOrderedMap का प्रस्ताव है लेकिन कोई भी थ्रेड-सुरक्षित नहीं है।

मैंने Google Guava से MapMaker पर स्विच किया है। आप CacheBuilder भी देख सकते हैं।

0

उम, सरल उत्तर एक monotonically बढ़ती कुंजी प्रदाता का उपयोग करना होगा कि आपके Comparator चालू है। AtomicInteger सोचें, और हर बार जब आप सम्मिलित करते हैं, तो आप तुलना के लिए उपयोग करने के लिए एक नई कुंजी बनाते हैं। यदि आप अपनी वास्तविक कुंजी को पूल करते हैं, तो आप OrderedKey<MyRealKeyType> का आंतरिक मानचित्र बना सकते हैं।

class OrderedKey<T> implements Comparable<OrderedKey<T>> { 
    T realKey; 
    int index; 
    OrderedKey(AtomicInteger source, T key) { 
    index = source.getAndIncrement(); 
    realKey = key; 
    } 
    public int compareTo(OrderedKey<T> other) { 
    if (Objects.equals(realKey, other.realKey)) { 
     return 0; 
    } 
    return index - other.index; 
    } 


} 

यह एक कस्टम तुलनित्र के लिए की जरूरत को समाप्त होता है, और आप एक अच्छे हे (1) विधि आकार की गणना करने (जब तक आप को हटा देते हैं, जो मामले में, उन लोगों के रूप में अच्छी तरह से गिनती है, तो आप सिर्फ घटा सकते देना "सभी सफल जोड़ों" से "सभी सफल हटाएं", जहां सफल अर्थ है कि वास्तव में एक प्रविष्टि बनाई गई थी या हटा दी गई थी)।

+0

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

संबंधित मुद्दे