2014-11-25 10 views
7

मुझे आपकी सलाह चाहिए। शुरुआत के लिए मैं पूर्व शर्त का वर्णन करना चाहता हूं।50/50 पढ़ने/लिखने के लिए समवर्ती संग्रह

  1. मैं किसी तीसरे पक्ष जावा डिफ़ॉल्ट java.lang.Object के hashCode() और equals() कार्यान्वयन के साथ वस्तुओं की है। Comparable इंटरफ़ेस लागू नहीं किया गया है। आकार महत्वहीन है।
  2. मुझे स्मृति में कुछ समय के लिए ऐसी वस्तुओं को स्टोर करने की आवश्यकता है। मैं 50/50 अनुपात में विभिन्न धागे से उन्हें पढ़ और लिखूंगा (लगभग 50% पढ़ता है और 50% लिखता है)।
  3. वस्तुओं का क्रम महत्वपूर्ण नहीं है। मैं सिर्फ दुकान से कुछ वस्तु लेने की संभावना लेना चाहता हूं, बस इतना ही। के साथ मेरा मतलब है और एक ही समय में हटा दें।
  4. निश्चित रूप से, मैं इसे सबसे कम मेमोरी खपत के साथ जितनी जल्दी हो सके काम करना चाहता हूं। मैं अपने कोड में किसी भी सिंक्रनाइज़ेशन से बचने की कोशिश कर रहा हूं।

सबसे पहले मैंने स्वयं को इस समस्या को हल करने का प्रयास किया है। मैंने उच्च स्मृति खपत के कारण तुरंत CopyOnWriteArray* संग्रह को खारिज कर दिया है। मैंने पढ़ा है कि दुर्लभ लिखने के मामले में उनका उपयोग करना बेहतर होता है। ConcurrentHashMap मेरी ज़रूरतों के लिए सामान्य स्वीट्स में मुझे बनाने के लिए रास्ता नहीं मिला ऑपरेशन परमाणु सिंक्रनाइज़ेशन के बिना। मैंने ConcurrentSkipListSet संग्रह पर अपनी जांच के साथ रोक दिया है। इसमें pollFirst विधि है जो पर बहुत अच्छा सूट ऑब्जेक्ट्स लेता है।

मैंने अपने समाधान को ConcurrentSkipListSet के आधार पर लागू किया है। मुझे एक छोटी सी जानकारी को छोड़कर सब कुछ ठीक काम करता है। जैसा कि मैंने उपरोक्त वस्तुओं का उल्लेख किया है, मैं Comparable लागू नहीं कर रहा हूं। तो चुने गए संग्रह का उपयोग करने के लिए मुझे किसी भी तरह Comparator लागू करना होगा। यहां इस इंटरफेस का मेरा कार्यान्वयन है। इस उदाहरण में मैंने अपने ऑब्जेक्ट प्रकार के बजाय सीधे java.lang.Object का उपयोग किया है। मैंने ऐसा किया है क्योंकि कारण कार्यान्वयन पूरी तरह से समान है, अंतर केवल कक्षा के सामान्य भाग में है।

import java.util.Comparator; 

public class ObjectComparator implements Comparator<Object> { 

    public int compare(Object o1, Object o2) { 
     return o1.hashCode() - o2.hashCode(); 
    } 
} 

इस कार्यान्वयन का विपक्ष स्पष्ट है। मैंने पाया है कि no guarantee है कि दो अलग-अलग ऑब्जेक्ट्स में अलग हैश कोड होंगे। ऐसे मामले में कुछ वस्तुओं को खोना संभव है जो स्वीकार्य नहीं है। मैंने अलग-अलग ऑब्जेक्ट्स के बराबर हैश कोड के मामले में कुछ यादृच्छिक संख्या वापस करने का विचार किया है, लेकिन मुझे यकीन नहीं है कि यह ConcurrentSkipListSet कार्यान्वयन को तोड़ नहीं देगा।

बताई गई स्थिति के बारे में मेरे दो सामान्य प्रश्न हैं।

  1. यह इस तरह के रूप में जिस तरह से मेरी वस्तु के लिए Comparator लागू करने के लिए विभिन्न वस्तुओं के लिए 0 नहीं लौटते करने और ConcurrentSkipListSet संचालनीयता रखने संभव है?
  2. क्या मेरे ऑब्जेक्ट्स को स्टोर करने का कोई और तरीका है?

आपके उत्तरों के लिए अग्रिम धन्यवाद।

+0

आपकी वस्तुएं कितनी बड़ी हैं? यदि आप सेफोरोर भारीपन के कारण <100 ऑब्जेक्ट्स हैं तो CopyOnWrite रणनीति सबसे अच्छी है। और यदि आपके संग्रह बहुत बड़े नहीं हैं तो आप बहुत ही कुशल एल्गोरिदम के साथ ईडन पीढ़ी के लिए सबकुछ फिट कर सकते हैं। – Taky

+0

@Taky संग्रह का आकार निर्दिष्ट नहीं है। यह 100 या 10k हो सकता है। मुझे नहीं पता। मैं इस समस्या को हल करने के लिए कुछ सामान्य तरीका खोजने की कोशिश कर रहा हूं। इसके अलावा मैंने आपकी टिप्पणी के दूसरे भाग को नहीं पकड़ा। "ईडन पीढ़ी" के साथ आपका क्या मतलब है? – artspb

+0

"ईडन पीढ़ी" से मेरा मतलब युवा जेवीएम ऑब्जेक्ट का पूल है। – Taky

उत्तर

3

शायद आप ConcurrentLinkedQueue की तलाश में हैं, यह FiFo (पहले बाहर में पहले) ऑर्डर के आधार पर आइटम संग्रहीत करेगा। इस वजह से hashcode और comparable आवश्यकताएं मौजूद हैं। किसी भी आंतरिक लॉकिंग के बिना, इस कतार का कार्यान्वयन बहुत ही कुशल है।

आपके पास एक कठिनाई है जो आपके पास है (जब ताले का उपयोग नहीं किया जाता है) यह है कि आप यह नहीं देख सकते कि संग्रह खाली नहीं है और फिर एक ले लें (क्योंकि यह आपकी जांच के बाद और आपकी कार्रवाई के बाद बदल सकता है)। take फ़ंक्शन null पर वापस आने पर कुछ भी मौजूद नहीं होगा। यदि आप डेटा के लिए मतदान नहीं करना चाहते हैं, तो आप BlockingQueue इंटरफेस को लागू करने वाले वर्गों का भी सहारा ले सकते हैं, यह उन कार्यों को प्रदान करता है जो डेटा उपलब्ध होने तक प्रतीक्षा करते हैं।

1

1: आप इस तरह के रूप में अपने तुलनित्र को लागू कर सकते हैं:

public int compare(Object o1, Object o2) { 
    if (o1 == o2) { 
     return 0; 
    } else { 
     int dif = o1.hashCode() - o2.hashCode(); 
     if (dif != 0) { 
      return dif; 
     } else { 
      return 1; //Might cause issues 
     } 
    } 
} 

2: आप किसी भी सामान्य संग्रह java.util का उपयोग कर सिंक्रनाइज़ कर सकते हैं।संग्रह। सिंक्रनाइज़ेशन चयन() (या कोई अन्य सिंक्रनाइज़ेशन-विधि)। उदाहरण के लिए, यदि आप एक लिंक्डलिस्ट को सिंक्रनाइज़ करते हैं, तो आप पर निकालें (इंडेक्स) का उपयोग ऑब्जेक्ट ले सकते हैं।

+0

1. मैंने अपने प्रश्न में इस तरह के कार्यान्वयन का उल्लेख किया है। क्या आप वाकई 'ConcurrentSkipListSet' तर्क' नहीं तोड़ेंगे? 2. हां, यह अच्छा विकल्प है। लेकिन उच्च लोड सिंक्रनाइज़ेशन के मामले में प्रदर्शन समस्याओं का कारण बन जाएगा। मैं इसे टालने की कोशिश कर रहा हूं। – artspb

+0

@Art एचएम मैं तुलनित्र के बारे में गलत पढ़ता हूं। मुझे लगता है कि आप ऑब्जेक्ट के साथ प्रत्येक ऑब्जेक्ट को एक तुलनात्मक रैपर में भी ऑर्डर के आधार पर रख सकते हैं जिसमें वे बनाए गए थे। क्या इससे काम हो जायेगा? –

+1

सामान्य रूप से इसे काम करना चाहिए। लेकिन कार्यान्वयन काफी जटिल होगा। उदाहरण के लिए मुझे इस मामले में 'वीक रेफरेंस' का उपयोग करना है ताकि ऑब्जेक्ट पर निर्भर न हो। इस समस्या के तकनीकी समाधान के रूप में यह काम करता है, लेकिन मेरे दृष्टिकोण से यह काफी बदसूरत लग रहा है। वैसे भी विचार के लिए धन्यवाद! – artspb

1

मेरी जरूरतों के लिए सामान्य सुइट में ConcurrentHashMap लेकिन मैं ले आपरेशन परमाणु

क्यों ConcurrentHashMap में remove का उपयोग नहीं करने के लिए रास्ता खोजने नहीं किया? ऐसा लगता है कि आपको क्या चाहिए।

+0

लेकिन 'निकालने' का उपयोग करने के लिए विधि मुझे पहले किसी वस्तु को प्राप्त करना है। जब तक मैं सफल नहीं हो जाता तब तक मैं प्रत्येक ऑब्जेक्ट को हटाने की कोशिश कर रहा हूं 'इटरेटर' के साथ कर सकता हूं। यदि बहुत सारे धागे हैं तो पहले से ही हटाए गए प्रविष्टियों को हटाने का प्रयास करने में काफी समय लगेगा। ऐसा इसलिए है क्योंकि 'ConcurrentHashMap' के 'इटरेटर' के माध्यम से आप मानचित्र के कुछ राज्यों के साथ काम कर रहे हैं, लेकिन वास्तविक डेटा के साथ नहीं। वास्तविक डेटा के साथ ऑपरेटिंग 'ConcurrentSkipListSet' की विपरीत साइट 'PollFirst()' विधि से। ऐसे मामले में यह बहुत तेज होना चाहिए। – artspb

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