2013-08-19 12 views
8

पर सिंक्रनाइज़ JSON-जावा पुस्तकालय (org.json.JSONArray) में मैं एक विधि-स्थानीय चर के चारों ओर एक synchronized ब्लॉक के साथ इस कोड स्निपेटआवश्यकता स्थानीय चर

public String toString(int indentFactor) throws JSONException { 
    StringWriter sw = new StringWriter(); 
    synchronized (sw.getBuffer()) { 
     return this.write(sw, indentFactor, 0).toString(); 
    } 
} 

मैं तुल्यकालन के लिए आवश्यकता समझ में नहीं आता पाया है यहां, केवल दी गई विधि के लिए स्थानीय है (और, बफर पर सिंक्रनाइज़ेशन क्यों है)। सिंक्रनाइज़ेशन वास्तव में यहां जरूरी है, और यदि, क्यों?

+8

यह अनावश्यक है। डिफ़ॉल्ट कन्स्ट्रक्टर के साथ, बफर एक नई तत्काल वस्तु है। 'buf = new StringBuffer(); 'कन्स्ट्रक्टर के अंदर। –

+8

ध्यान दें कि org.json लाइब्रेरी का लेखक एक जावास्क्रिप्ट प्रोग्रामर है, जावा प्रोग्रामर नहीं, और यह तथ्य पूरे कोड में प्रदर्शित होता है। गंभीर JSON प्रसंस्करण के लिए, Google की Gson लाइब्रेरी का उपयोग करने पर विचार करें। –

उत्तर

7

यह एक प्रदर्शन अनुकूलन हो सकता है। ओरेकल जेवीएम में, पहले से आयोजित लॉक को पुनः प्राप्त करना बहुत तेज़ है। संभवतः, write कॉल स्ट्रिंगबफर में कई कॉल कर रही है। write पर कॉल करने से पहले लॉक करके, लॉक जारी किए जाने के बजाय उन सभी कॉल के माध्यम से आयोजित किया जाएगा और प्रत्येक कॉल के लिए पुनः अधिग्रहण किया जाएगा।

+0

जावा 6 के रूप में, लॉकिंग का मतलब है कि एक अनचाहे लॉक प्राप्त करना वैसे भी तेज़ है। –

+0

@ क्रिसजेस्टर-यंग - हाँ, मुझे नहीं पता कि विशेष प्रदर्शन अनुकूलन अभी भी कितना प्रासंगिक है (या कभी भी था)। – jtahlborn

+0

मुझे प्रत्येक कॉल_ के लिए रिलीज़ और पुनः अधिग्रहित _being को कम नहीं किया गया है। 'लिखना()' कॉल 'राइटर' पर बिल्कुल कोशिश नहीं करता है और 'सिंक्रनाइज़' नहीं करता है। लॉक को ओपी के प्रश्न में 'toString (int) 'विधि के अंदर, केवल एक बार अधिग्रहण और रिलीज़ किया जाता है। –

6
StringWriter के लिए

खाली निर्माता इसलिए synchronized ब्लॉक अनावश्यक है,

/** 
* Create a new string writer using the default initial string-buffer 
* size. 
*/ 
public StringWriter() { 
    buf = new StringBuffer(); 
    lock = buf; 
} 

कुछ भी साझा नहीं किया जाता है।

जब तक ... write अन्य धागे पर प्रतिनिधि करता है, लेकिन मुझे गंभीरता से संदेह है।

1

getBuffer() रिटर्न एक StringBuffer, और प्रलेखन के अनुसार एक StringBuffer पहले से ही सिंक्रनाइज़ है:

स्ट्रिंग बफ़र्स से अधिक थ्रेड द्वारा उपयोग के लिए सुरक्षित हैं। विधियों को सिंक्रनाइज़ किया जाता है जहां आवश्यक हो ताकि किसी भी विशेष उदाहरण पर सभी ऑपरेशन इस तरह व्यवहार कर सकें कि वे कुछ धारावाहिक क्रम में होते हैं जो कि प्रत्येक व्यक्तिगत थ्रेड द्वारा किए गए विधि कॉल के क्रम के अनुरूप होते हैं।

इसका मतलब है कि StringBuffer पर फिर से सिंक्रनाइज़ करना पूरी तरह से अधिक है। StringWriter में परिवर्तन स्वचालित रूप से सिंक्रनाइज़ हो जाएंगे क्योंकि यह आंतरिक रूप से सिंक्रनाइज़ StringBuffer का उपयोग करता है।

चूंकि StringWriter उदाहरण विधि कॉल के लिए स्थानीय है, इसलिए एक ही समय में एक ही उदाहरण तक पहुंचने के लिए कई धागे असंभव हैं, जो सिंक्रनाइज़ेशन को अनावश्यक बनाता है।

0

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

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