2009-11-21 17 views
16

मैं समझता हूं कि हैशटेबल जैसे संग्रह सिंक्रनाइज़ किए गए हैं, लेकिन क्या कोई मुझे कैसे समझा सकता है यह यह काम करता है, और किस बिंदु पर पहुंच समवर्ती कॉल तक सीमित है? उदाहरण के लिए, मान लीजिए कि मैं इस तरह कुछ iterators का उपयोग करते हैं:जब इटरेटर का उपयोग किया जाता है तो संग्रह के सिंक्रनाइज़ेशन की व्याख्या करें?

Hashtable<Integer,Integer> map = new Hashtable<Integer,Integer>(); 

void dosomething1(){ 
    for (Iterator<Map.Entry<Integer,Integer>> i = map.entrySet().iterator(); i.hasNext();){ 
     // do something 
    } 
} 
void dosomething2(){ 
    for (Iterator<Map.Entry<Integer,Integer>> i = map.entrySet().iterator(); i.hasNext();){ 
     // do something 
     // and remove it 
     i.remove(); 
    } 
} 
void putsomething(int a, int b){ 
    map.put(a,b); 
} 
void removesomething(int a){ 
    map.remove(a); 
} 
var clear(){ 
    map = new Hashtable<Integer,Integer>(); 
} 

अगर कोई अलग धागे से यादृच्छिक पर इन कार्यों बुला मेरे साथ नुकसान कर रहे हैं किसी को समझाने कृपया कर सकते हैं? इटेटरेटर, विशेष रूप से, इसके सिंक्रनाइज़ेशन को कैसे करता है, खासकर जब यह एंट्रीसेट() का उपयोग कर रहा है, जो सिंक्रनाइज़ेशन की भी आवश्यकता होगी? क्या होता है अगर स्पष्ट() कहा जाता है जबकि लूप में से एक प्रगति पर है? क्या होगा अगर हटाए गए() किसी आइटम को हटा दें जो अभी तक dosomething1() में समवर्ती पाश द्वारा संसाधित नहीं किया गया है?

किसी भी मदद के लिए धन्यवाद! जावा में संग्रह से अधिक

उत्तर

34

पुनरावृत्ति सुरक्षित थ्रेड नहीं है, भले ही आप सिंक्रनाइज़ रैपर में से एक (Collections.synchronizedMap(...)) का उपयोग कर रहे हैं:

यह आवश्यक है कि उपयोगकर्ता मैन्युअल रूप से जब से अधिक पुनरावृत्ति लौटे नक्शे पर सिंक्रनाइज़ अपने संग्रह से किसी भी दृश्य:

Map m = Collections.synchronizedMap(new HashMap()); 
... 
Set s = m.keySet(); // Needn't be in synchronized block 
... 
synchronized(m) { // Synchronizing on m, not s! 
    Iterator i = s.iterator(); // Must be in synchronized block 
    while (i.hasNext()) 
     foo(i.next()); 
} 

Java Collection Framework docs

सिंक्रनाइज़ संग्रह करने के लिए अन्य कॉल, सुरक्षित हैं के रूप में आवरण वर्गों उन्हें synchronized ब्लॉक, जो उनके मॉनिटर के रूप में आवरण संग्रह का उपयोग के साथ चारों ओर:

public int size() { 
    synchronized(this) { 
     return collection.size(); 
    } 
} 

collection मूल संग्रह होता है। यह पुनरावृत्ति सामग्री को छोड़कर, संग्रह/मानचित्र द्वारा उजागर सभी विधियों के लिए काम करता है।

मानचित्र का मुख्य सेट उसी तरह सिंक्रनाइज़ किया गया है: सिंक्रनाइज़ रैपर मूल कुंजी सेट को बिल्कुल वापस नहीं करता है। इसके बजाए, यह संग्रह के मूल कुंजी सेट का एक विशेष सिंक्रनाइज़ रैपर देता है। यह एंट्री सेट और वैल्यू सेट पर भी लागू होता है।

+0

उत्तर फिक्स्ड: मॉनीटर का इस्तेमाल वास्तव में रैपर संग्रह है, मूल नहीं। – Dirk

+0

यह बहुत उपयोगी है और बहुत अच्छी तरह प्रस्तुत किया गया है। मुझे एक स्रोत खोजने में परेशानी हो रही थी जो स्पष्ट रूप से बताती है, इसलिए बहुत बहुत धन्यवाद! – DivideByHero

+0

"जावा में संग्रह पर इटरेशन थ्रेड सुरक्षित नहीं है, भले ही आप सिंक्रनाइज़ किए गए रैपरों में से एक का उपयोग कर रहे हों" ओ_ओ भयानक – rkarajan

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

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