2013-09-25 12 views
5

मैं नीचे वर्गक्या क्लास पर लॉक है, क्लास वैरिएबल भी लॉक करता है? - जावा

public class Example{ 

    public static List<String> list = new ArrayList<String>(); 

    public static void addElement(String val){ 
     synchronized(list){ 
      list.add(val); 
     } 
    } 

    public static synchronized void printElement(){ 
     Iterator<String> it = list.iterator(); 
     while(it.hasNext()){ 
      //print element 
     } 
    } 
} 

इटरेटर() printElement विधि में कॉल ConcurrentModificationException फेंक विल है? मूल सवाल यह है कि यदि क्लास ऑब्जेक्ट पर लॉक अधिग्रहित किया गया है (जैसा कि प्रिंट एलिमेंट विधि में किया गया है), क्या यह कक्षा के सदस्यों/चरों को भी लॉक करेगा? कृपया उत्तर के साथ मेरी मदद करें।

उत्तर

6

वर्ग पर एक ताला है, ताले वर्ग चर भी? - जावा

आपकी लॉक नहीं, बल्कि आपके वर्ग अपने उदाहरण पर है। और नहीं, यह केवल उदाहरण को ताला लगा देता है।

क्या प्रिंटरमेंट विधि में इटरेटर() कॉल ConcurrentModificationException फेंक देगा?

यदि यह विधि उस कोड में पुनरावृत्ति के दौरान सूची को संशोधित करेगी तो यह होगा। लेकिन उस वर्ग में अपने कोड के सभी भी सिंक्रनाइज़ करता है, और आप कुछ भी बाहर को अपनी कक्षा में उस सूची के लिए एक संदर्भ नहीं दिया है, तो आप जानते हैं कि केवल कि विधि में कोड चल रहा है।

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

public static void printElement(){ 
//   ^--- No `synchronized ` here unless you REALLY need it for other reasons 

    synchronized (list) { 
     Iterator<String> it = list.iterator(); 
     while(it.hasNext()){ 
      //print element 
     } 
    } 
} 

आप संदर्भ देने रहे हैं, तो और चाहते हैं वास्तव में सुनिश्चित करें, या तो Collections.synchronizedList या java.util.concurrent package से कुछ की गई सूची का उपयोग करें।

+0

दो ताले का उपयोग करके कुछ बुरा डेडलॉक्स हो सकता है, इसलिए मैं विधि हस्ताक्षर – Simiil

+0

@ सिमीयल में सिंक्रनाइज़ कर दूंगा: * किसी भी * लॉक के परिणामस्वरूप डेडलॉक हो सकता है। :-) लेकिन हाँ, मैंने इसे हटा दिया है, क्योंकि यह तब तक जरूरी नहीं होना चाहिए जब तक कि प्रश्न में कोई कारण न दिखाया जाए। –

+0

एक लॉक वास्तव में कुछ भी ताला लगा देता है। यह कुछ ताला लगाने के लिए प्रयोग किया जाता है :) – extraneon

0

ArrayListConcurrentModificationException फेंकता है जब संग्रह पर समवर्ती रूप से संशोधन किया जाएगा या संग्रह संरचना में परिवर्तन के मामले में पुनरावृत्ति होगी।

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

synchronized (list) { 
    Iterator<String> it = list.iterator(); 
    while(it.hasNext()){ 
     //print element 
    } 
} 
1

नहीं, एक सिंक्रनाइज़ विधि ऑब्जेक्ट चर को लॉक नहीं करती है, एक सिंक्रनाइज़ विधि केवल this लॉक कर देगी।

आपका कोड थ्रेड सुरक्षित नहीं है, क्योंकि आप addElement और printElement पर विभिन्न ऑब्जेक्ट्स पर लॉक कर रहे हैं। सूची को पुनरावृत्ति करते समय सम्मिलन को रोकने के लिए कुछ भी नहीं है, अगर दोनों विधि को समवर्ती रूप से कहा जाता है।

0

आपने कभी भी addElement विधि नहीं कहा है, इसलिए इस कोड स्निपेट पर लॉकिंग का कोई प्रभाव नहीं पड़ता है। जब आप किसी संग्रह पर पुनरावृत्त होते हैं, तो यदि आप उसी संग्रह से तत्व को सम्मिलित/हटाते हैं तो आपको ConcurrentModificationException मिल जाता है। Javadoc से:

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

1
Will the iterator() call in the printElement method throw ConcurrentModificationException? 

हाँ, अगर addElement और printElement दो धागे से पुकारा जाता है से बचने के simultaneously.To, ConcurrentModificationException, आप CopyOnWriteList इस्तेमाल कर सकते हैं।

if the lock on class object is acquired(as done in printElement method), will it lock the class members/ variables too? 

synchonized विधि printElement, अपनी कक्षा में इस object.Hence यह अभ्यस्त एक और सिंक्रनाइज़ विधि या synchornized (यह) ब्लॉक एक ही समय में कहा जा करने के लिए अनुमति की लॉक प्राप्त होगा, अगर वहाँ है किसी भी।

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