2009-03-10 22 views
13

मैं कई टुकड़ों से एक स्ट्रिंग का निर्माण कर रहा हूं और ऐसा करने के लिए StringBuffer या StringBuilder का उपयोग करना चाहता हूं। जावा 5 डॉक्स से, मुझे लगता है कि StringBuilder चेतावनी है कि StringBuilder कीजावा स्ट्रिंगबिल्डर और थ्रेड सुरक्षा

उदाहरण से अधिक थ्रेड द्वारा उपयोग के लिए सुरक्षित नहीं हैं के साथ, पसंद किया जाता है जब संभव।

इस बयान से, मैं समझता हूँ कि मैं एक ही StringBuilder उदाहरण से अधिक थ्रेड द्वारा साझा नहीं होना चाहिए। लेकिन क्या इस मामले के बारे में:

//Is this safe? 
//foo() is called simultaneously by multiple threads 
String foo(String a, String b) { 
    return new StringBuilder(a).append(b).toString(); 
} 

यहाँ एक ही समय में समारोह में एक से अधिक थ्रेड हो सकता है, एक ही समय में StringBuilder वर्ग का उपयोग कर (जैसे, स्थैतिक चर का साथ-साथ उपयोग, यदि कोई हो तो), लेकिन प्रत्येक धागे का अपना अलग उदाहरण StringBuilder होगा। प्रलेखन से, मैं यह तय नहीं कर सकता कि यह कई धागे द्वारा उपयोग के रूप में गिना जाता है या नहीं।

+0

foo() को स्थिर विधि बनाने में कुछ लाभ हो सकता है, क्योंकि यह किसी भी आवृत्ति चर को स्पर्श नहीं करता है। – Kip

+0

@ किप: कक्षा पर निर्भर करता है। लेकिन कुछ बार आप पॉलिमॉर्फिक परिचालन करना और विधि को स्थैतिक तरीके से लागू करना चाहते हैं। – OscarRyz

+0

स्ट्रिंग.कोनकैट का उपयोग करना तेज होगा, लेकिन मुझे लगता है कि यह सिर्फ एक उदाहरण है। –

उत्तर

19

यह बिल्कुल ठीक है। स्थानीय चरों को थ्रेड सुरक्षा के साथ कोई समस्या नहीं है जब तक कि वे उदाहरण या कक्षा चर को एक्सेस या उत्परिवर्तित न करें।

11

हां, यह सुरक्षित है, क्योंकि स्ट्रिंगबिल्डर ऑब्जेक्ट का उपयोग केवल स्थानीय रूप से किया जाता है (प्रत्येक थ्रेड कॉलिंग foo() अपना स्वयं का स्ट्रिंगबिल्डर उत्पन्न करेगा)।

तुम भी ध्यान देना चाहिए कि कोड आप पोस्ट व्यावहारिक रूप से यह द्वारा उत्पन्न बाईटकोड के समान है:

String foo(String a, String b) { 
    return a + b; 
} 
+0

आप उस बाइटकोड को कैसे देखते हैं? – OscarRyz

+0

@ ऑस्कर: javap -c

+0

यह भी देखें: http://stackoverflow.com/questions/272535/how-do-i-decompile-java-class-files – Kip

4

अन्य उत्तर के साथ सहमत - बस एक ध्यान दें।

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

+0

यह स्ट्रिंगबिल्डर का तर्क है। अधिकांश बार सिंक्रनाइज़ेशन की आवश्यकता नहीं थी। – OscarRyz

+0

हां, जो आपको आश्चर्यचकित करता है कि उन्होंने समांतर स्ट्रिंगबिल्डर बनाने के बजाय स्ट्रिंगबफर को फिर से क्यों नहीं लिखा। उस ऐप के लिए पिछड़ा संगतता रखने के लिए जो नोडेटर्मेनिस्टिक स्ट्रिंग बनाता है? –

+1

हो सकता है कि आप मल्टीथ्रेड किए गए ऐप के किसी प्रकार की मेमोरी लॉगिंग के लिए स्ट्रिंगबिल्डर का उपयोग कर रहे हों? यकीन नहीं है कि आप ऐसा क्यों करेंगे ... – Kip

3

मुझे यकीन नहीं है कि इस कोड की आवश्यकता है, क्योंकि जावा स्वचालित रूप से स्ट्रिंगबिल्डर चुनता है। यदि आपके पास कोई प्रदर्शन समस्या नहीं है, तो + बी के साथ जाएं।

एक प्रदर्शन की जरूरत के मामले में, कि कोशिश:

return new StringBuilder(
a.length() + b.length()).append(a).append(b).toString(); 

यह सही ढंग से बफर आकार और यह आकार बदलने और रास्ते पर इकट्ठा करने के लिए कचरा बनाने से वीएम से बचाता है।

6

आपके पास जो कोड है वह सुरक्षित है।

यह कोड नहीं है।

public class Foo 
{ 
    // safe 
    private final static StringBuilder builder; 

    public static void foo() 
    { 
     // safe 
     builder = new StringBuilder(); 
    } 

    public static void foo(final String a) 
    { 
     // unsafe 
     builder.append(a); 
    } 

    public synchronized void bar(final String a) 
    { 
     // safe 
     builder.append(a); 
    } 
} 

स्थानीय चर है कि केवल स्थानीय डेटा का उपयोग threadsafe मुद्दों जरूरत नहीं है। क्लास या इंस्टेंस विधि/चर स्तर पर दिखाई देने वाले डेटा से निपटने के बाद आपके पास केवल थ्रेडसेफ समस्याएं हो सकती हैं।

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