2013-09-27 11 views
5

संग्रह ढांचे में, आंतरिक सिंक्रनाइज़ेशन आंतरिक एक (वेक्टर, हैशटेबल इत्यादि) से तेज क्यों है? भले ही वे दोनों एक ही तंत्र का उपयोग करते हैं?आंतरिक सिंक्रनाइज़ेशन आंतरिक से तेज क्यों है?

आंतरिक और बाहरी सिंक्रनाइज़ेशन का वास्तव में क्या अर्थ है और वे एक-दूसरे से अलग कैसे होते हैं?

अगर कोई उदाहरण के साथ समझा सकता है तो यह वास्तव में सहायक है।

+2

मामूली तरफ: सिंक्रनाइज़ संग्रहों का उपयोग करने से थ्रेड-सुरक्षित कोड लिखने के लिए आमतौर पर बहुत बेहतर तरीके होते हैं। (जैसे लॉक-फ्री समवर्ती डेटा स्ट्रक्चर जो अवरुद्ध करने की आवश्यकता नहीं होने पर न्यूनतम ओवरहेड लेते हैं।) – millimoose

उत्तर

9

आंतरिक और बाहरी सिंक्रनाइज़ेशन का वास्तव में क्या अर्थ है और वे एक-दूसरे से अलग कैसे होते हैं?

बाहरी तुल्यकालन जब फोन करने वाले (आप) synchronized कीवर्ड या अन्य ताले का उपयोग किसी अन्य वर्ग के खिलाफ की रक्षा करने के लिए एक से अधिक थ्रेड द्वारा पहुँचा जा रहा है। आमतौर पर इसका उपयोग किया जाता है यदि प्रश्न में कक्षा स्वयं सिंक्रनाइज़ नहीं है - SimpleDateFormat एक प्रमुख उदाहरण है। यदि आप समवर्ती संग्रह से निपटने के दौरान भी थ्रेड के बीच सिग्नलिंग की आवश्यकता होती है तो इसका भी उपयोग किया जा सकता है।

आंतरिक सिंक्रनाइज़ेशन आंतरिक एक (वेक्टर, हैशटेबल इत्यादि) से तेज क्यों है? भले ही वे दोनों एक ही तंत्र का उपयोग करते हैं?

बाहरी तुल्यकालन नहीं जरूरी तेज है। आम तौर पर एक वर्ग निर्धारित कर सकता है जब इसे synchronized ब्लॉक में सभी विधि कॉल को कॉल करने वाले कॉलर के बजाय कोड के एक महत्वपूर्ण अनुभाग के आसपास सिंक्रनाइज़ करने की आवश्यकता होती है।

आप सामान्य सिफारिश के बारे में नहीं उपयोग Vector और HashTable और बदले Collections.synchronizedList(...) या synchronizedMap(...) तरीकों का उपयोग करने के लिए बात कर रहे हैं, तो यह क्योंकि Vector और HashTable वर्ष/वर्ष पुराने वर्गों के रूप में देखा जाता है। एक लपेटा ArrayList या HashMap एक बेहतर समाधान के रूप में देखा जाता है।

कभी-कभी @ क्रिस ने बताया कि बाह्य सिंक्रनाइज़ेशन तेज हो सकता है जब आपको कक्षा में एक दूसरे के बाद कई बदलाव करने की आवश्यकता होती है। एक बार बाहरी रूप से लॉक करके और फिर कक्षा में कई बदलाव करने से, यह आंतरिक रूप से लॉक होने वाले प्रत्येक परिवर्तन से बेहतर काम करता है। एक लॉक एकाधिक लॉक कॉल से तेज होने पर एक पंक्ति में बनाई जाती है।

अगर कोई उदाहरण के साथ समझा सकता है तो यह वास्तव में सहायक होता है।

Vector के बजाय, आम तौर पर लोग बेहतर प्रदर्शन के रूप में एक लिपटे ArrayList की अनुशंसा करते हैं। यह गैर-सिंक्रनाइज़ ArrayList कक्षा को एक रैपर वर्ग में लपेटता है जो बाह्य इसे सिंक्रनाइज़ करता है।

public class Foo { 
    private int count; 
    public void addToCount() { 
     count++; 
     log.info("count increased to " + count); 
    } 
} 

आप बाहरी तुल्यकालन इस्तेमाल कर सकते हैं और addToCount() के लिए हर कॉल लपेट:

List<Foo> list = Collections.synchronizedList(new ArrayList<Foo>()); 

बनाम सामान्य रूप में बाहरी आंतरिक के संदर्भ में, निम्न वर्ग है कि आप एक से अधिक थ्रेड समवर्ती इसका इस्तेमाल करने की अनुमति देना चाहते हैं पर विचार

synchronized (foo) { 
    foo.addToCount(); 
} 

या वर्ग ही आंतरिक तुल्यकालन का उपयोग करें और यो के लिए ताला कर सकते हैं: एक synchronized ब्लॉक में यू। यह बेहतर प्रदर्शन करती है क्योंकि लकड़हारा वर्ग ताला का एक हिस्सा होने की जरूरत नहीं है:

public void addToCount() { 
    int val; 
    synchronized (this) { 
     val = ++count; 
    } 
    // this log call should not be synchronized since it does IO 
    log.info("count increased to " + val); 
} 
बेशक

, Foo वर्ग वास्तव में इस मामले में एक AtomicInteger का उपयोग करें और आंतरिक रूप से अपने स्वयं के reentrance का ध्यान रखना चाहिए:

private final AtomicInteger count = new AtomicInteger(0); 
public void addToCount() { 
    int val = count.incrementAndGet() 
    log.info("count increased to " + val); 
} 
+0

अच्छे उदाहरणों के साथ स्पष्टीकरण के लिए धन्यवाद ...... – Rajeev

7

मान लें कि आप एक बैंक में काम करते हैं। हर बार जब आपको सुरक्षित उपयोग करने की आवश्यकता होती है, तो इसे अनलॉक करने की आवश्यकता होती है, और फिर जब आप इसका उपयोग कर लेते हैं तो फिर से लॉक हो जाते हैं।

अब मान लें कि आपको सुरक्षित में 50 बक्से ले जाने की आवश्यकता है।

  1. व्यक्तिगत रूप से, खुले हिस्से पर प्रत्येक बॉक्स ले और (अत्यंत भारी) दरवाजा हर बार
  2. लॉक बैंक के सामने के दरवाजे को बंद करने और तिजोरी खुला छोड़ दें, बिना 50 यात्राएं कर: आपके पास दो विकल्प आंतरिक वॉल्ट दरवाजा छूना

कौन सा तेज़ है? (पहला विकल्प आंतरिक सिंक्रनाइज़ेशन है, दूसरा विकल्प बाह्य सिंक्रनाइज़ेशन है।)

+0

अच्छा सादृश्य लेकिन यदि आपको बैंक से बाहर निकलना है तो बाहरी खराब है हर बार। आप शहर को लॉक नहीं कर सकते हैं और न ही देश – Mordan

+0

@ मॉर्डन मुझे लगता है कि आप रूपक को बहुत दूर खींच रहे हैं। कंप्यूटर पर एब्स्ट्रैक्शन वास्तव में नगर पालिकाओं द्वारा बाधित नहीं होते हैं। जावा जेवीएम इसका एक अच्छा उदाहरण है - जब वे कचरा संग्रह करते हैं, तो उनके कुछ कार्यान्वयन "दुनिया को रोकें" लॉकिंग करते हैं जो सचमुच सबकुछ तब तक चलने से रोकता है जब तक यह पूरा नहीं हो जाता है। मैं यह नहीं कह रहा हूं कि आपको इसके लिए प्रयास करना चाहिए, लेकिन इसकी अनदेखी नहीं है। –

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