2010-06-30 13 views
13

हे सब, मैं विरासत में मिला कुछ कोड पर काम कर रहा हूं, ऐसा लगता है कि एक थ्रेड एक बूलियन सदस्य चर सेट कर रहा है जबकि एक और धागा थोड़ी देर में इसे जांच रहा है। क्या यह वास्तव में ठीक काम करेगा या क्या मुझे इसे बूलियन var पर सिंक्रनाइज़ गेटर्स या सेटर्स का उपयोग करने के लिए बदलना चाहिए?बुलियन सदस्य युद्धों की सेटिंग सिंक्रनाइज़ करने की आवश्यकता है?

+0

अब तक अच्छे उत्तरों, मैं सोच रहा था कि जबकि लूप वैरिएबल को कैश कर रहा है, यह स्थानीय रूप से जांचने की कोशिश कर रहा है। मैं अब अस्थिर जोड़ रहा हूं और चर को एक सिंक्रनाइज़ गेटर और सेटर में डाल रहा हूं। –

+3

मुझे लगता है कि आपने जवाब (और दस्तावेज़ीकरण) को ठीक से नहीं पढ़ा है, खासकर टॉम हौटिन से। अस्थिर चर के उपयोग को सिंक्रनाइज़ करना एक ऑक्सीमोरोन है। –

+0

मैं मानता हूं कि अस्थिरता आपके बूलियन वैरिएबल की रक्षा करेगी और सुनिश्चित करें कि इसे ठीक से अपडेट किया जा रहा है और पढ़ा जा रहा है, लेकिन आपको बड़ी तस्वीर देखने की ज़रूरत है और सुनिश्चित करें कि आपके ऑब्जेक्ट हमेशा एक सतत स्थिति में हैं। –

उत्तर

7

सिंक्रनाइज़ किया पढ़ने के मामले में पहुंचता है और bool की तरह एक आदिम लिख रहे हैं या उन्हें अस्थिर घोषित int बहुत होगा। जब एक धागे अन्य धागे को पढ़ता है तो लेखन समाप्त हो जाता। चर कभी अमान्य स्थिति में नहीं होगा।

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

एक अस्थिर जावा चर की घोषणा का अर्थ है:

  1. इस वेरिएबल का मान कभी नहीं संचित किया जाएगा धागे की स्थानीय स्तर पर: सभी पढ़ता है और "मुख्य स्मृति" के लिए सीधे जाना होगा लिखते हैं;
  2. के रूप में परिवर्तनीय कार्यों तक पहुंच हालांकि यह सिंक्रनाइज़ ब्लॉक में संलग्न है, पर सिंक्रनाइज़ किया गया है।

हम कहते हैं दूसरी बात में, प्रोग्रामर कम से कम (और शायद सबसे JVM कार्यान्वयन में) क्योंकि "के रूप में यद्यपि कार्य करता है" कोई वास्तविक ताला वस्तु शामिल नहीं है।

http://www.javamex.com/tutorials/synchronization_volatile.shtml

+0

'अस्थिर' को जेएलएस और जेवीएम स्पेक में बिल्कुल निर्दिष्ट किया गया है। हालांकि, यह परिणामों को समझने के मुकाबले कहीं अधिक इस्तेमाल होता प्रतीत होता है। –

+0

@ टॉम हौटिन - एक को सीमाओं को समझने की जरूरत है। यह सीमित स्थितियों में एक शक्तिशाली उपकरण है। –

+1

जबकि आपने जो कहा वह बूलियन (और कुछ मामलों में int) primitives के बारे में सच है, int ++ जैसे संचालन करते समय int से सावधान रहें। हालांकि यह एक ही ऑपरेशन प्रतीत होता है, यह वास्तव में नहीं है और इस तरह के मामले में अस्थिरता का उपयोग करना पर्याप्त नहीं है। –

2

लगभग निश्चित रूप से आपको उच्च स्तर पर लॉकिंग जोड़ने की आवश्यकता होगी। खेतों में एकल पहुंच के आसपास बस synchronized जोड़ना शायद ही कभी मदद करता है। घटक संचालन स्वतंत्र रूप से थ्रेड-सुरक्षित होने पर समग्र संचालन थ्रेड-सुरक्षित नहीं होंगे।

उदाहरण के तौर पर एक थ्रेड-सुरक्षित दस्तावेज़ की सामग्री को हटाने पर विचार करें। दस्तावेज़ दो प्रासंगिक थ्रेड-सुरक्षित संचालन प्रदान करता है: दो इंडेक्स और लम्बाई ऑपरेशन के बीच सामग्री को हटा रहा है। तो आप लंबाई प्राप्त करते हैं और शून्य से लंबाई तक हटाते हैं, है ना? खैर, एक दौड़ है क्योंकि दस्तावेज़ लंबाई को पढ़ने और सामग्री को हटाने के बीच लंबाई बदल सकता है। संचालन के बाद ऑपरेशन थ्रेड-सुरक्षित बनाने का कोई तरीका नहीं है। (उदाहरण स्विंग पाठ से लिया।)

+0

+1 बूलियन वैरिएबल से अधिक देखने के लिए कुछ परिप्रेक्ष्य जोड़ने के लिए अच्छा बिंदु। –

+0

आपका बिंदु अच्छी तरह से बनाया गया है लेकिन समग्र तर्क पेश करने के लिए पूछे गए प्रश्न के आधार पर कोई संदर्भ नहीं है। सवाल एक बुलियन पाठक/लेखक समस्या के बारे में था। Showboating? – bjg

+0

@bjg थ्रेडिंग में संदर्भ शामिल है। यह स्वाभाविक रूप से गैर-स्थानीय है। मेरा मानना ​​है कि यह संभावना है कि हाथ में समस्या एक बुलियन से आगे जाती है। निश्चित रूप से मुश्किल कोड के साथ एक विशेष मामला समस्या हल करने के लिए क्षेत्र में नए व्यक्ति के लिए यह अनुपयोगी होगा। –

-1

मेरा सुझाव है कि बूलियन अस्थिर घोषित किया और कहा कि पढ़ने और लिखने

+0

यह उलझन में लगता है। (इसके अलावा 'अस्थिर' आश्चर्यजनक अनुपयोगी है (कम स्तर पर उत्साहित) क्योंकि ऑपरेशंस को आम तौर पर कई घटक संचालन की आवश्यकता होती है।) –

+0

@tackline क्या आपका मतलब यह उलझन में है क्योंकि यह बेल्ट और ब्रेसिज़ दृष्टिकोण है? यदि ऐसा है, तो जब मैं समझता हूं कि जावा प्रोग्रामिंग मॉडल यह सुझाव दे सकता है कि अपने आप पर अस्थिर पर्याप्त है, तो मैं अभी भी उन सभी जेवीएम कार्यान्वयन के संबंध में इस दावे पर शक कर सकता हूं, विशेष रूप से जब म्यूट-कोर वातावरण पर चल रहा हो। किसी भी घटना में - भले ही मेरा पायरानिया स्पष्ट हो - भले ही अपने आप पर अस्थिरता रखने वालों को पर्याप्त संकेत न हो कि कुछ महत्वपूर्ण बात है कि उन्हें – bjg

+0

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

0

आप जावा का उपयोग करते हैं 1.5+, आप Condition तुल्यकालन आदिम उपयोग करना चाहिए।

यदि आप लिंक का पालन करते हैं तो इसका उपयोग करने के तरीके पर इसका एक अच्छा उदाहरण है।

0

यह अगर यह एक सादा बूलियन है काम करने के लिए गारंटी नहीं है, धागे से एक अद्यतन बूलियन जावा की स्मृति मॉडल की वजह से नहीं देख सकते हैं, आप

  • एक तुल्यकालन गेटर/सेटर बना सकते हैं या
  • बूलियन को अस्थिर घोषित करने के लिए घोषित करें, http://www.ibm.com/developerworks/java/library/j-jtp06197.html अस्थिर अंडरस्टास्टिंग के लिए एक अच्छा संसाधन है।

ध्यान रखें कि इनमें से कोई भी "काम" नहीं कर सकता है अगर यह बूलियन पढ़ने वाला थ्रेड बूलियन के पिछले मूल्य पर निर्भर करता है - तो यह उस बुलियन में परिवर्तनों को याद कर सकता है, उदाहरण के लिए

Thread1:

while(foo.myVolatileBoolean) { 
... 
} 

Thread2:

foo.myVolatileBoolean = false; //thread 1 might never catch thisone. 
... 
foo.myVolatileBoolean = true; 

यदि यह एक मुद्दा है और आप बूलियन में परिवर्तन की निगरानी के लिए/प्रतीक्षा() का उपयोग करें, (सूचित) या Condition

की जरूरत
संबंधित मुद्दे