2012-12-17 59 views
35

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

यह अच्छी तरह से पता है कि पैरामीटर के रूप में अपरिवर्तनीय वस्तुओं के साथ स्थैतिक विधियां थ्रेड सुरक्षित हैं और म्यूटेबल ऑब्जेक्ट्स नहीं हैं।

यदि मेरे पास java.util.Date के कुछ हेरफेर के लिए उपयोगिता विधि है और यह विधि java.util.Date के उदाहरण को स्वीकार करती है, तो यह विधि थ्रेड सुरक्षित नहीं होगी। फिर पैरामीटर गुजरने के तरीके को बदलने के बिना इसे धागा सुरक्षित कैसे बनाया जाए?

public class DateUtils { 

    public static Date getNormalizeDate(Date date) { 
     // some operations 
    } 
} 

कक्षा javax.faces.context.FacesContext उत्परिवर्तनीय भी है? क्या यह इस वर्ग के उदाहरण को ऐसी स्थिर उपयोगिता विधि में पास करने के लिए सुरक्षित है?

कक्षाओं की यह सूची, जिनके उदाहरण पैरामीटर के रूप में पारित किए जा सकते हैं या नहीं पारित किए जा सकते हैं; तो ऐसे उपयोगिता वर्गों के कोड लिखते समय हमें किन बिंदुओं को ध्यान में रखना चाहिए?

+2

क्यों वोट नीचे और एक करीबी अनुरोध? क्या यह एक गलत सवाल है? –

+0

क्या आपने इस स्थिर विधि को 'सिंक्रनाइज़ किया' माना है? –

+6

@AndrewLogvinov हाँ मैंने सोचा है। लेकिन मैं यह जानकर बिना सिंक्रनाइज़ किए गए एक विधि बनाना चाहता हूं कि मैं ऐसा क्यों कर रहा हूं। किस परिस्थितियों में हम एक स्थैतिक विधि सिंक्रनाइज़ कर सकते हैं? –

उत्तर

46

यह अच्छी तरह से ज्ञात है कि पैरामीटर के रूप में अपरिवर्तनीय वस्तुओं के साथ स्थैतिक विधियां थ्रेड सुरक्षित और परिवर्तनीय वस्तुएं नहीं हैं।

मैं इसे लड़ूंगा। किसी विधि को पारित तर्क एक स्टैक पर संग्रहीत होते हैं, जो एक प्रति-थ्रेड मुहावरे है।

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

आपके द्वारा पोस्ट की गई विधि थ्रेड-सुरक्षित है। यह कोई राज्य बनाए रखता है और केवल अपने तर्कों पर ही कार्य करता है।

मैं आपको Java Concurrency in Practice, या जावा में थ्रेड सुरक्षा के लिए समर्पित एक समान पुस्तक को दृढ़ता से अनुशंसा करता हूं। यह एक जटिल विषय है जिसे कुछ स्टैक ओवरफ्लो उत्तरों के माध्यम से उचित रूप से संबोधित नहीं किया जा सकता है।

+0

ग्रेट उत्तर, धन्यवाद – Keerthivasan

3

मैं विधि (प्रारंभ करने योग्य) ऑब्जेक्ट की प्रतिलिपि बनाने की अनुशंसा करता हूं जैसे ही विधि शुरू होती है और मूल पैरामीटर की बजाय प्रति का उपयोग करें।

कुछ इस

public static Date getNormalizeDate(Date date) { 
    Date input = new Date(date.getTime()); 
    // ... 
} 
+2

यह तिथि के लिए अच्छा लगता है, लेकिन कस्टम ऑब्जेक्ट्स के लिए संभव नहीं होगा, खासकर यदि यह एक तृतीय पक्ष कस्टम ऑब्जेक्ट है जिसे वह संपादित नहीं कर सकता है। –

11

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

जो कोड इसे कॉल करता है वह थ्रेड सुरक्षित नहीं हो सकता है लेकिन यह एक और चर्चा है। उदाहरण के लिए, दिनांक थ्रेड सुरक्षित नहीं है, अगर कॉलिंग कोड किसी अन्य थ्रेड द्वारा लिखी गई तारीख को पढ़ता है, तो आपको दिनांक लेखन और पढ़ने कोड में उचित सिंक्रनाइज़ेशन का उपयोग करना होगा।

4

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

0

यहां मैं इस बारे में सोचता हूं: कैंपसाइट (यह एक स्थिर विधि है) की कल्पना करें।एक कैंपर के रूप में, मैं अपने रक्सकैक में ऑब्जेक्ट्स का एक गुच्छा ला सकता हूं (यह स्टैक पर दिए गए तर्क हैं)। कैम्पसाइट मुझे अपने तम्बू और मेरे शिविर, आदि को रखने के लिए एक जगह प्रदान करता है, लेकिन यदि कैंपसाइट का एकमात्र चीज मुझे अपनी वस्तुओं को संशोधित करने की अनुमति देती है तो यह थ्रेडसेफ है। कैम्पसाइट भी पतली हवा (FirePit firepit = new FirePit();) से चीजें बना सकता है, जो ढेर पर भी बनाया जाता है।

किसी भी समय मैं अपने सभी सामानों के साथ गायब हो सकता हूं और किसी अन्य कैंपर्स में से एक दिखाई दे सकता है, आखिरकार वे गायब होने के आखिर में क्या कर रहे थे। इस कैम्पसाइट में अलग-अलग धागे को अन्य धागे में कैंपसाइट को बनाए गए ढेर पर ऑब्जेक्ट तक पहुंच नहीं होगी।

कहें कि केवल एक शिविर है (कैम्पस्टो की एक वस्तु, अलग तत्काल नहीं)। अगर कल्पना के कुछ हिस्सों से मैं एक कैम्पस्टो ऑब्जेक्ट साझा कर रहा हूं तो बहु-थ्रेडिंग विचार हैं। मैं अपने शिविर को चालू नहीं करना चाहता हूं, गायब हो जाता हूं और फिर कुछ अन्य कैंपर बंद होने के बाद फिर से दिखाई देता है - मैं हमेशा जांच कर रहा हूं कि मेरा गर्म कुत्ता किया गया था और यह कभी नहीं होगा। आपको कुछ सिंक्रनाइज़ेशन कहीं भी रखना होगा ... कैम्पसाइट श्रेणी में, कैंपसाइट को कॉल करने वाली विधि में, या कैंपसाइट में ही ... लेकिन Duncan Jones कहता है, "यह एक अलग मामला है"।

ध्यान दें कि भले ही हम गैर स्थैतिक कैम्पिंग वस्तुओं की अलग instantiations में डेरा डाले हुए थे, एक campStove साझा करने में एक ही बहु सूत्रण विचार करना होगा।