2013-04-05 3 views
11

मैं कुछ जावा कोड को पढ़ने के लिए, और पाया इन कार्यों:जावा सिंक्रनाइज़ किए गए कीवर्ड को आदिम गेटर/सेटर विधि पर आवश्यक है?

synchronized void setConnected(boolean connected){ 
    this.connected = connected; 
} 

synchronized boolean isConnected(){ 
    return connected; 
} 

मुझे आश्चर्य है अगर तुल्यकालन यहां किसी भी समझ में आता है, या सिर्फ लेखक सिंक्रनाइज़ कीवर्ड के लिए की जरूरत समझ में नहीं आया?

मुझे लगता है कि सिंक्रनाइज़ किया गया है यहां बेकार है। या मैं गलत हूँ?

+0

सिंक्रनाइज़ संशोधक केवल समझ में आता है अगर एक से अधिक धागा 'connected' चर तक पहुँचने के लिए प्रयास करने के लिए जा रहा है हो सकता है। –

+0

कृपया http://stackoverflow.com/questions/11459543/java-synchronized-getters-and-setters देखें। यह आपके प्रश्न का उत्तर देता है और इसे बड़े संदर्भ में अच्छी तरह से रखता है। – prashant

+2

इन क्यू + ए को पढ़ें http://stackoverflow.com/questions/11459543/java-synchronized-getters-and-setters – Zelldon

उत्तर

19

कीवर्ड synchronized थ्रेड-सुरक्षा सुनिश्चित करने का एक तरीका है। सावधान रहें: सिड्रनाइज़ेशन के बिना int को बढ़ाने वाले दो धागे की वजह से डेडलॉक्स की तुलना में थ्रेड-सुरक्षा के लिए (रास्ता) और अधिक अनुपलब्ध अपडेट हैं।

निम्नलिखित वर्ग पर विचार करें:

class Connection { 
    private boolean connected; 
    synchronized void setConnected(boolean connected){ 
    this.connected = connected; 
    } 
    synchronized boolean isConnected(){ 
    return connected; 
    } 
} 

से अधिक थ्रेड Connection का एक उदाहरण का हिस्सा है और एक धागा setConnected(true) कॉल करता है, synchronized बिना यह संभव है कि अन्य थ्रेड isConnected() == false दिखाई दे रहा है। synchronized कीवर्ड गारंटी देता है कि सभी थ्रेड फ़ील्ड के वर्तमान मान को देखते हैं।

अधिक तकनीकी शर्तों में, synchronized कीवर्ड मेमोरी बाधा (संकेत: google that) सुनिश्चित करता है।

अधिक जानकारी में: एक मॉनीटर जारी करने से पहले किए गए प्रत्येक लेखन (यानी, synchronized ब्लॉक छोड़ने से पहले) एक ही मॉनीटर प्राप्त करने के बाद किए गए प्रत्येक पढ़ने द्वारा (यानी, उसी ऑब्जेक्ट पर सिंक्रनाइज़ करने वाले ब्लॉक को दर्ज करने के बाद))। जावा में, नामक कुछ है जो (संकेत: google that) से पहले होता है, जो कि "मैंने इस क्रम में कोड लिखा था, इसलिए इस क्रम में कोड को निष्पादित किया गया" के रूप में छोटा नहीं है। synchronized का उपयोग करना एक पूर्व-संबंध संबंध स्थापित करने का एक तरीका है और गारंटी देता है कि धागे स्मृति को देखते हैं क्योंकि आप उन्हें देखने की अपेक्षा करेंगे।

इसी मामले में, समान गारंटी प्राप्त करने का एक और तरीका, synchronized कीवर्ड को खत्म करना होगा और volatile फ़ील्ड को चिह्नित करना होगा। volatile द्वारा प्रदान की गई गारंटी निम्नानुसार है: अस्थिर लेखन से पहले थ्रेड द्वारा किए गए सभी लिखने को उसी फ़ील्ड के बाद के अस्थिर पढ़ने के बाद थ्रेड पर दिखाई देने की गारंटी दी जाती है।

एक अंतिम टिप्पणी के रूप में, इस विशेष मामले में यह synchronized accessors के बजाय एक volatile क्षेत्र का उपयोग करने के लिए, क्योंकि दो दृष्टिकोण एक ही गारंटी देता है और volatile -field दृष्टिकोण प्रदान बेहतर हो सकता है अलग धागे से क्षेत्र के लिए एक साथ पहुंच की अनुमति देता है (यदि synchronized संस्करण में बहुत अधिक विवाद है तो प्रदर्शन में सुधार हो सकता है)।

+0

हालांकि, कुछ एक थोड़ा बेहतर अभ्यास के रूप में एक अंतिम मैदान पर सिंक करने के लिए, पर विचार इस धागे पर श्री स्कीट द्वारा सुझाया गया: http://stackoverflow.com/questions/6910807/synchronization-of-non-final-field –

+0

मेरा प्रश्न शायद बेवकूफ है, लेकिन आपका बूलियन 'अस्थिर' नहीं होना चाहिए? – Pith

+0

@pith: नहीं, चूंकि सभी तक पहुंच (यानी, सभी पढ़ता है और लिखता है) सिंक्रनाइज़ किए गए तरीकों के अंदर किया जाता है। –

2

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

7

मेमोरी स्थिरता त्रुटियों को रोकने के लिए सिंक्रनाइज़ेशन की आवश्यकता है, http://docs.oracle.com/javase/tutorial/essential/concurrency/memconsist.html देखें। कम से कम है कि मेरी समझ है - यह ठोस मामला volatile में हालांकि बहुत अधिक कुशल समाधान

private volatile boolean connected; 

void setConnected(boolean connected){ 
    this.connected = connected; 
} 

boolean isConnected(){ 
    return connected; 
} 
संबंधित मुद्दे

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