2010-05-21 12 views
32

वेक्टर सिंक्रनाइज़ किया गया है, ArrayList सिंक्रनाइज़ नहीं है, लेकिन हम Collections.synchronizedList(aList) द्वारा एक ArrayList सिंक्रनाइज़ कर सकते हैं, जो बेहतर और तेज प्रदर्शन करेगा?वेक्टर बनाम संग्रह। सिंक्रनाइज़लिस्टसूची (ArrayList)

+1

यदि यह सी # है, तो कृपया अपने प्रश्न को "सी #" या ".NET" से टैग करें। – FrustratedWithFormsDesigner

+1

आप एक परीक्षा क्यों लिखते हैं और पता नहीं लगाते? – skaffman

+0

क्या आप उपयोग पैटर्न की व्याख्या कर सकते हैं? 1) कई लिखते हैं/कई पढ़ते हैं 2) कुछ लिखते हैं, कई पढ़ते हैं, 3) कई लिखते हैं, कुछ पढ़ते हैं 4) कुछ/कुछ को अनुकूलन की आवश्यकता नहीं है – TJR

उत्तर

4

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

int i = 0; 
while (i < list.size()) 
{ 
    if (testSomeCondition(list.get())) { 
    list.remove(i); 
    else 
    i++; 
} 

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

दौड़ को ठीक करने के लिए हमें संग्रह पर पूरे ऑपरेशन को सिंक्रनाइज़ करना होगा या ऐसा करने के लिए जावा 5 कॉन्सुरेंसी लॉक्स का उपयोग करना होगा।

synchronized (list) { 
    int i = 0; 
    while (i < list.size()) 
    { 
    if (testSomeCondition(list.get())) { 
     list.remove(i); 
    else 
     i++; 
    } 
} 

कोड के इस ब्लॉक अब सुरक्षित थ्रेड है के बाद से केवल एक धागा एक समय में पाश निष्पादित कर सकते हैं। और अब सिंक्रनाइज़ संग्रह का उपयोग करने का कोई कारण नहीं है। हम एक वेक्टर के बजाय एक ArrayList का उपयोग कर सकते हैं और उन सभी सिंक्रनाइज़ कॉल पर प्रदर्शन दंड बचा सकते हैं।

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

+9

"सिंक्रनाइज़ संग्रह समय की बर्बादी है।" - बहुत सामान्य। सिंक्रनाइज़ संग्रह का उद्देश्य है। आप सिर्फ एक उदाहरण दे रहे हैं कि उन्हें गलत तरीके से कैसे उपयोग करें। स्ट्रॉ मैन तर्क। – thejoshwolfe

+0

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

+1

जावा 1.3 और इससे पहले सिंक्रनाइज़ेशन धीमा था। आधुनिक जावा में यह बेहतर है। http://www.ibm.com/developerworks/java/library/j-jtp04223/index.html इसके अलावा, फिर से स्ट्रॉ विशिष्ट तर्कों के साथ। कोई भी ऐसी स्थिति के साथ सिंक्रनाइज़ेशन का उपयोग नहीं करता है जिसे सिंगल-थ्रेडेड कहा जाता है। आपका पहला उदाहरण सिर्फ सादा खराब प्रोग्रामिंग है और इसके लिए कोई संग्रह कभी भी तैयार नहीं हो सकता है। आप बस इस बारे में सोचना चाहिए कि आप किस संग्रह का उपयोग करते हैं, इस पर ध्यान दिए बिना कि क्या परमाणु है या नहीं। ArrayList में कोड निकालें() पर एक नज़र डालें और आप देखेंगे कि सूची की अखंडता को बनाए रखने के लिए इस विधि को सिंक्रनाइज़ करने की आवश्यकता क्यों है। – Gus

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