2013-02-25 80 views
7

चलो कहते हैं कि मैं निम्नलिखित करते हैं,स्ट्रिंग थ्रेडसेफ प्राप्त/सेट है?

public class Foo{ 
    private String bar; 

    public String getBar(){ 
     return bar; 
    } 

    public void setBar(String bar){ 
     this.bar = bar; 
    } 
} 

इन तरीकों स्वचालित रूप से threadsafe String वर्ग के अपरिवर्तनीय प्रकृति के कारण कर रहे हैं, या कुछ ताला तंत्र की आवश्यकता है?

+2

मुझे लगता है कि आप सेटर में 'स्ट्रिंग' का मतलब है। –

+0

@TheodorosChatzigiannakis, हाँ, मेरी गलती! फिक्स्ड। – mre

+1

संबंधित सी # प्रश्न: http://stackoverflow.com/questions/3595114/why-are-immutable-objects-thread-safe – PermGenError

उत्तर

18

नहीं, यह थ्रेडसेफ नहीं है। Foo परिवर्तनशील है, इसलिए यदि आप सुनिश्चित करना चाहते हैं कि अलग अलग धागे bar का एक ही मूल्य देखते हैं - जो है, स्थिरता - या तो:

  • barvolatile, या
  • बनाने के तरीकों synchronized करें, या
  • AtomicReference<String> का उपयोग करें।

bar के पढ़ने और लिखने स्वयं परमाणु हैं, लेकिन परमाणुता थ्रेड सुरक्षा नहीं है।

http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html


जावा संगामिति के गहन कवरेज के लिए, Java Concurrency in Practice (aka JCIP) की एक प्रति हड़पने।

+4

+1 या बस 'बार' को 'अंतिम' के रूप में घोषित करें, इसलिए संदर्भ को किसी अन्य मान पर फिर से असाइन नहीं किया जा सकता है।बेशक, तब कोई सेटटर नहीं होगा :) –

+1

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

+0

... जिज्ञासा से बाहर, वास्तव में उनमें से कोई भी काम करते हैं? मेरा मतलब है, अगर आपकी वास्तविक समस्या दौड़ की स्थिति है, तो यह अभी भी हो सकती है, 'अस्थिर' या 'सिंक्रनाइज़' के बावजूद - यह केवल 'विंडो' को कम करता है जिसमें यह हो सकता है, है ना? या मुझसे यहां कुछ छूट रहा है? –

4

नहीं, सुरक्षित नहीं।

यह फू उत्परिवर्तनीय व्यवहार है; स्ट्रिंग की अपरिवर्तनीयता फू को अर्जित नहीं करती है।

public class Foo{ 
    private String bar; 

    public synchronized String getBar(){ 
     return bar; 
    } 

    public synchronized void setBar(String bar){ 
     this.bar = bar; 
    } 
} 
+0

+1 'getBar()' सिंक्रनाइज़ करने के बारे में क्या? हो सकता है कि कुछ थ्रेड 'बार' के लिए एक नया मान सेट करें, जबकि अन्य थ्रेड 'बार' पढ़ रहे हों। –

+0

क्षमा करें, आप मुझे कोई समझ नहीं रहे हैं। मुझे लगता है कि आपकी टिप्पणियां केवल इस मुद्दे को भ्रमित कर रही हैं। – duffymo

+0

@duffymo थ्रेड में सिंक्रनाइज़ किए गए सेटर गारंटी स्थिरता के साथ एक गैर-सिंक्रनाइज़ गेटर करता है? –

7

आप संदर्भ सेट कर रहे हैं, और String की अपरिवर्तनीयता खेल में नहीं आती है। आप String की सामग्री को प्रभावित नहीं कर रहे हैं।

3

नहीं, यह धागा सुरक्षित नहीं है।

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

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

  • कोई संबंधित समस्या नहीं^_^