2009-08-29 14 views
5

को देखते हुए निम्नलिखित कोड:एक चर (थ्रेड) की थ्रेड-सुरक्षित सेटिंग?

public class FooBar { 

public static volatile ConcurrentHashMap myConfigData = new ConcurrentHashMap();  

} 

public class UpdaterThread implements Runnable { 

run { 

//Query the Data from the DB and Update the FooBar config Data 
FooBar.myConfigData = ConfigDataDAO.getLatestConfigFromDB(); 
} 
} 

(एक निर्वाहक हर 5 मिनट के माध्यम से) थ्रेड-कक्षा myConfigData Membervariable नियमित रूप से अपडेट हो जाएगा। "बाहरी" थ्रेड थ्रेडसेफ (परमाणु) में myConfigData की सेटिंग है, या क्या मुझे हर पढ़ने और लिखने के ऑपरेशन को myConfigData Variable में सिंक्रनाइज़ करना है?

संपादित करें: प्रश्न यह नहीं है कि ConcurrentHashMap थ्रेडसेफ है (यह जावाडोक के अनुसार है) बल्कि ConconrentHashMap को MyConfigData सदस्य चर में स्वयं की सेटिंग के बजाय। यह चर कई धागे द्वारा "एक बार" पढ़ और लिखा जा सकता है, इसलिए सवाल यह है कि सेटिंग परमाणु है या नहीं। मुझे लगता है कि यह सामान्यीकृत किया जा सकता है "क्या जावा संदर्भ चर परमाणु है या नहीं?"।

(मैं भी यह अस्थिर यह एक अलग मुद्दा है बना दिया है और atomicity साथ कोई संबंध नहीं है - मेरे सवाल - बल्कि "अन्य धागे में दृश्यता" और होता है-पहले संबंध।।)

उत्तर

12

संदर्भों को प्रतिस्थापित करना सुरक्षित है। Java language Specification देखें:

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

FooBar.myConfigData.put(somekey, somevalue); 

तो यह निश्चित रूप से सुरक्षित थ्रेड है, के रूप में: अद्यतन द्वारा आप ConcurrentHashMap अंदर एक प्रविष्टि के ऊपर लिख मतलब तो

+3

@ अज्ञात: उद्धृत पाठ यह नहीं कहता कि आप क्या सोचते हैं !! वास्तव में, JLS में अगले बुलेट इस कहते हैं: "स्पष्ट तुल्यकालन के अभाव में, एक कार्यान्वयन एक आदेश है कि आश्चर्य की बात हो सकती है में मुख्य स्मृति अद्यतन करने के लिए नि: शुल्क है इसलिए प्रोग्रामर जो आश्चर्य से बचने के लिए स्पष्ट तुल्यकालन का उपयोग करना चाहिए पसंद करती हैं।। " –

+1

@ अज्ञात: ओपी का कोड सुरक्षित होने का एकमात्र कारण यह है कि उन्होंने चर को 'अस्थिर' घोषित कर दिया है। –

+3

@ स्टीफन मुझे लगता है कि प्रश्न का मुख्य बिंदु असाइनमेंट की परमाणुता के बारे में था। यही कारण है कि मैंने कल्पना के इस हिस्से को उद्धृत किया। यदि मैं सही ढंग से समझता हूं, तो अस्थिरता का उपयोग नहीं होने पर भी इस परमाणु की गारंटी है। हालांकि यह हो सकता है कि अन्य धागे चर को अद्यतन नहीं देखेंगे और "पुराना" संदर्भ देखना जारी रखें। हालांकि एक धागा कभी "किसी अन्य वस्तु या भ्रष्ट संदर्भ मान का संदर्भ" नहीं देखेगा। – Wolfgang

0

ConcurrentHashMp है:

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

जावाडॉक्स का कहना है कि यह थ्रेड सुरक्षित है।

कॉन्फ़िगरेशन सेट करने के लिए बहुत सारे काम और सीपीयू चक्र की तरह लगता है। क्या यह वास्तव में यह गतिशील है? या आप महीने में एक बार बदलते हैं और जब आप करते हैं तो बस सेवा उछाल की आवश्यकता होती है?

+0

आपके उत्तर के लिए धन्यवाद! मैंने अपना प्रश्न और स्पष्ट करने और मेरे प्रश्न को संपादित करने की कोशिश की। –

0

, (§17.4 देख वहाँ लंबे समय तक और डबल मूल्यों के लिए एक विशेष अपवाद नहीं है।) डफिमो ने कहा।

आप एक नया मान के साथ myConfigData चर अधिलेखित करना चाहते हैं:

FooBar.myConfigData = new ConcurrentHashMap(); 

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

संपादित करें: प्रश्न ConcurrentHashMap मौसम नहीं है threadsafe (यह जावाडोक के अनुसार है), लेकिन myConfigData सदस्य चर में ConcurrentHashMap के ही नहीं बल्कि सेटिंग है। यह चर कई धागे द्वारा "एक बार" पढ़ और लिखा जा सकता है, इसलिए सवाल यह है कि सेटिंग परमाणु है या नहीं। मुझे लगता है कि इसे सामान्यीकृत किया जा सकता है, जावा संदर्भ चर परमाणु या नहीं है।

(मैंने इसे अस्थिर बना दिया। यह एक अलग मुद्दा है और परमाणुता (मेरा प्रश्न) के साथ कुछ भी नहीं है बल्कि "अन्य धागे में दृश्यता" और रिश्ते से पहले होता है)।

असल में 'अस्थिर' atomicity के लिए है, कुछ भी नहीं दृश्यता को प्रभावित करता है, एक सार्वजनिक चर हमेशा किसी भी धागा करने के लिए दिखाई जाएगी।

+0

आपके उत्तर के लिए भी बहुत बहुत धन्यवाद! –

2

volatile की गारंटी देता है atomicity, दृश्यता और एक 'स्मृति बाधा' (इसके लिए गूगल, अगर आप को पता है कि क्या मतलब चाहते हैं) के रूप में कार्य करता है - कम से कम जावा 5. के बाद से इसलिए यह वास्तव में क्या आप चाहते हैं।

0

यदि आप अनिश्चित महसूस करते हैं तो आप AtomicReference का उपयोग कर सकते हैं।

हालांकि मुझे लगता है कि आपके मामले में अस्थिर कौशल पर्याप्त हो सकता है।

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