2012-05-01 11 views
6

मुझे अक्सर बड़े संग्रह या तारों की सरणी को एन्कोड या डीकोड करना होता है। उनके माध्यम से पुनरावृत्त करने और स्थिर URLDecoder.decode (स्ट्रिंग, "यूटीएफ -8") का उपयोग करने के अलावा, क्या वहां कोई पुस्तकालय हैं जो इस प्रकार के ऑपरेशन को और अधिक सक्षम बनाएंगे?क्या कोई सामान्य जावा लाइब्रेरी है जो स्ट्रिंग के संग्रह के लिए यूआरएल एन्कोडिंग/डिकोडिंग को संभालती है?

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

+0

जब तक कि स्थिर विधि URLDecoder क्लास में स्थिर चर पर निर्भर न हो, प्रत्येक विधि कॉल अलग-अलग ढेर पर जाती है और थ्रेड सुरक्षित होती है। मुझे कोई कारण नहीं दिख रहा है कि क्यों URLDecoder.decode (...) को साझा संसाधनों तक पहुंच की आवश्यकता होगी। – Thomas

उत्तर

7

JDK URLDecoder कुशलता से लागू नहीं किया गया के माध्यम से पुनरावृत्ति सुझाव है। सबसे विशेष रूप से, आंतरिक रूप से यह स्ट्रिंगबफर पर निर्भर करता है (जो URLDecoder के मामले में अनावश्यक रूप से सिंक्रनाइज़ेशन प्रस्तुत करता है)। अपाचे कॉमन्स URLCodec प्रदान करता है, लेकिन प्रदर्शन के संबंध में भी इसी तरह के मुद्दे होने की सूचना मिली है, लेकिन मैंने सत्यापित नहीं किया है कि अभी भी हाल के संस्करण में यह मामला है।

Mark A. Ziesemer URLDecoder के साथ मुद्दों और प्रदर्शन के संबंध में कुछ समय पहले एक पोस्ट लिखा था। उन्होंने कुछ बग रिपोर्ट लॉग की और एक पूर्ण प्रतिस्थापन लिखना समाप्त कर दिया। क्योंकि यह इसलिए है, मैं कुछ प्रमुख अंश यहां उद्धृत कर देंगे, लेकिन क्या तुम सच में यहाँ पूरे स्रोत लेख को पढ़ने करना चाहिए: http://blogger.ziesemer.com/2009/05/improving-url-coder-performance-java.html

चयनित उद्धरण:

जावा जावा में इस कार्यक्षमता का एक डिफ़ॉल्ट कार्यान्वयन प्रदान करता है .net.URLEncoder और java.net.URLDecoder। दुर्भाग्यवश, यह सर्वोत्तम प्रदर्शन नहीं कर रहा है, दोनों एपीआई के साथ-साथ कार्यान्वयन के भीतर विवरणों के कारण दोनों के कारण। URLEncoder के संबंध में Sun.com पर कई प्रदर्शन-संबंधित बग दर्ज किए गए हैं।

एक विकल्प है: अपाचे कॉमन्स कोडेक से org.apache.commons.codec.net.URLCodec। (कॉमन्स कोडेक बेस 64 एन्कोडिंग के लिए एक उपयोगी कार्यान्वयन भी प्रदान करता है।) दुर्भाग्य से, कॉमन्स 'URLCodec जावा के URLEncoder/URLDecoder के समान मुद्दों में से कुछ को पीड़ित करता है।

...दोनों JDK और कॉमन्स के लिए

अनुशंसाएँ:

जब निर्माण "बफ़र" वर्गों के किसी भी है, उदा बाइटएरे ऑटपुटस्ट्रीम, चारएरेराइटर, स्ट्रिंगबिल्डर, या स्टिंगबफर, अनुमानित क्षमता अनुमानित और पास-इन करें। जेडीके का URLEncoder वर्तमान में अपने स्ट्रिंगबफर के लिए ऐसा करता है, लेकिन इसे अपने CharArrayWriter उदाहरण के लिए भी करना चाहिए। कॉमन का URLCodec इसे इसके ByteArrayOutputStream उदाहरण के लिए करना चाहिए। यदि कक्षा ' डिफ़ॉल्ट बफर आकार बहुत छोटे हैं, तो उन्हें को नए, बड़े बफर में कॉपी करके आकार बदलना पड़ सकता है - जो वास्तव में "सस्ता" ऑपरेशन नहीं है। यदि कक्षाओं के डिफ़ॉल्ट बफर आकार बहुत बड़े हैं, तो स्मृति अनावश्यक रूप से बर्बाद हो सकती है।

दोनों कार्यान्वयन चार्टसेट पर निर्भर हैं, लेकिन केवल उन्हें को उनके स्ट्रिंग नाम के रूप में स्वीकार करते हैं। चार्सेट नाम लुकअप के लिए एक सरल और छोटा कैश प्रदान करता है - केवल अंतिम 2 वर्णमाला का उपयोग करता है। यह पर भरोसा नहीं होना चाहिए, और दोनों को इंटरऑपरेबिलिटी कारणों के लिए चार्सेट उदाहरणों को भी स्वीकार करना चाहिए।

दोनों कार्यान्वयन केवल निश्चित आकार के इनपुट और आउटपुट को संभालते हैं। जेडीके का यूआरएलएनकोडर केवल स्ट्रिंग उदाहरणों के साथ काम करता है। कॉमन्स 'URLCodec स्ट्रिंग्स पर भी आधारित है, लेकिन बाइट [] सरणी के साथ भी काम करता है। यह डिज़ाइन-स्तरीय बाधा है जो अनिवार्य रूप से बड़े या परिवर्तनीय-लंबाई इनपुट के कुशल प्रसंस्करण को रोकता है। इसके बजाए, "स्ट्रीम-सपोर्टिंग" इंटरफेस जैसे CharSequence, Appendable, और java.nio's Buffer बाइटबफर और चारबफर के कार्यान्वयन को समर्थित किया जाना चाहिए।

...

ध्यान दें कि com.ziesemer.utils.urlCodec 3x अधिक के रूप में तेजी से JDK URLEncoder के रूप में है, और अधिक के रूप में तेजी से 1.5x JDK URLDecoder के रूप में। (JDK के URLDecoder तेजी URLEncoder से था, तो वहाँ सुधार के लिए के रूप में ज्यादा कक्ष नहीं था।)

मुझे लगता है कि अपने सहयोगी URLDecode थ्रेड-सुरक्षित नहीं है सुझाव देने के लिए गलत है। यहां अन्य उत्तरों विस्तार से समझाते हैं।

संपादित करें [2012-07-03] - बाद में टिप्पणी ओपी

सुनिश्चित नहीं हैं कि द्वारा पोस्ट की गई है, तो आप और अधिक विचारों या नहीं देख रहे थे प्रति? आप सही हैं कि यदि आप एक परमाणु संग्रह के रूप में सूची में काम करना चाहते हैं, तो आपको अपनी विधि के बाहर संदर्भों सहित सूची में सभी पहुंच सिंक्रनाइज़ करना होगा। हालांकि, यदि आप मूल सूची से संभावित रूप से भिन्न लौटाई गई सूची सामग्री के साथ ठीक हैं, तो किसी संग्रह से तारों के "बैच" पर संचालन के लिए एक ब्रूट फोर्स दृष्टिकोण जो अन्य धागे द्वारा संशोधित किया जा सकता है, ऐसा कुछ दिखाई दे सकता है:

/** 
* @param origList will be copied by this method so that origList can continue 
*     to be read/write by other threads. 
* @return list containing decoded strings for each entry that was 
      in origList at time of copy. 
*/ 
public List<String> decodeListOfStringSafely(List<String> origList) 
     throws UnsupportedEncodingException { 
    List<String> snapshotList = new ArrayList<String>(origList); 
    List<String> newList = new ArrayList<String>(); 

    for (String urlStr : snapshotList) { 
     String decodedUrlStr = URLDecoder.decode(urlStr, "UTF8"); 
      newList.add(decodedUrlStr); 
    } 

    return newList; 
} 

यदि यह मदद नहीं करता है, तो मुझे अभी भी यकीन नहीं है कि आप क्या कर रहे हैं और आप बेहतर, एक नया, संक्षिप्त, प्रश्न बनाने के लिए बेहतर सेवा देंगे। यदि आप यही पूछ रहे थे, तो सावधान रहें क्योंकि संदर्भ के बाहर यह उदाहरण कई कारणों से एक अच्छा विचार नहीं है।

+0

धन्यवाद। मुझे शायद इसे दो अलग-अलग प्रश्नों में तोड़ना चाहिए: एक जावा पुस्तकालय के बारे में एन्कोडिंग/डिकोडिंग पूरे संग्रह या स्ट्रिंग के सरणी और थ्रेड सुरक्षा समस्या के बारे में एक। डब्लूआरटी अपाचे का URLCodec, ऐसा लगता है कि यह अभी भी एक समय में एक स्ट्रिंग या ऑब्जेक्ट पर काम करता है। प्रदर्शन तुलना आप दिखाए जाते हैं उपयोगी हैं। – jrws

+0

थ्रेड सुरक्षा समस्या WRT, मुझे अधिक संदर्भ प्रदान करना चाहिए था (या किसी अन्य प्रश्न के लिए समस्या छोड़ दी है, कृपया नोब को क्षमा करें)। जहां तक ​​यह जाता है, थ्रेड सुरक्षा समस्या उत्पन्न हुई क्योंकि मानों की जगह प्रतिस्थापन करने के लिए संग्रह एक विधि तर्क है: सार्वजनिक foo (सूची तार)। संग्रह को मूल्य द्वारा ही बुलाया जाता है, लेकिन जिन वस्तुओं का संदर्भ है वे अभी भी ऑब्जेक्ट्स के संदर्भ हैं, इसलिए ऐसा लगता है कि सिंक्रनाइज़ेशन करना सबसे सुरक्षित बात है, क्योंकि इस संग्रह के कॉलर्स उपयोग पर मेरा कोई नियंत्रण नहीं है। इस तरह कुछ ... – jrws

+0

... सार्वजनिक foo (सूची तार) {सूची decodedStrings = संग्रह। synchronizedList (तार); सिंक्रनाइज़ (डीकोडेडस्ट्रिंग्स) {के लिए (स्ट्रिंग डीकोडेड स्ट्रिंग: डीकोडेडस्ट्रिंग्स) {decodedString = URLDecoder.decode (डीकोडेड स्ट्रिंग, "यूटीएफ -8")}};} – jrws

0

अपाचे में URLCodec है जिसका उपयोग एन्कोडिंग डिकोडिंग के लिए किया जा सकता है।

यदि आपकी स्थैतिक विधि स्थानीय चर या अंतिम प्रारंभिक चर पर काम करती है तो यह पूरी तरह से थ्रेड सुरक्षित है।

पैरामीटर स्टैक पर रहते हैं और वे पूरी तरह से थ्रेड सुरक्षित हैं, अंतिम स्थिरांक अपरिवर्तनीय हैं इसलिए इन्हें बदला नहीं जा सकता है।

के बाद कोड पूरी तरह से सुरक्षित थ्रेड जाता है: यदि अंतिम चर जिसका अर्थ है आप पुन: असाइन नहीं कर सकते परिवर्तनशील हैं

public static String encodeMyValue(String value){ 
    // do encoding here 
} 

देखभाल लिया जाना चाहिए, लेकिन आप अपने आंतरिक प्रतिनिधित्व (गुण) बदल सकते हैं।

0

थ्रेड सुरक्षा वास्तव में स्थिर कार्यों के साथ वास्तव में आवश्यक नहीं है (या यह एक डिजाइन विफलता है)। खासकर नहीं, अगर कक्षा में स्थिर वैरिएबल तक पहुंच भी नहीं है।

मैं समारोह आप से पहले इस्तेमाल का उपयोग कर, और संग्रह

0

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

तो अपने मामले में आप इस urldecoding या एन्कोडिंग के शीर्ष पर सिंक्रनाइज़ विधि लिख सकते हैं जिसके द्वारा आप थ्रेड सुरक्षा को बाहरी रूप से लागू कर सकते हैं।

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

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