2010-09-07 12 views
13

मेरे पास एक साधारण बीन @ एंटीटी Message.java है जिसमें कुछ सामान्य गुण हैं। उस वस्तु की जीवन-चक्र के रूप में इस प्रकार हैक्या मुझे BlockingQueue का उपयोग करते समय अतिरिक्त सिंक्रनाइज़ेशन की आवश्यकता है?

संदेश के आरंभ होने थ्रेड ए, जो फिर एक blockingQueue

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

उन परिस्थितियों को देखते हुए, क्या मुझे गेटर्स/सेटर्स को सिंक्रनाइज़ करने की आवश्यकता है? शायद गुण अस्थिर बनाते हैं? या मैं सिंक्रनाइज़ेशन के बिना बस छोड़ सकते हैं?

धन्यवाद और उम्मीद है कि मैं यहां जो कुछ भी कर रहा हूं उसे स्पष्ट कर सकता हूं।

उत्तर

25

नहीं, आप वस्तु गुणों में पहुंच सिंक्रनाइज़, या यहाँ तक सदस्य चर पर volatile उपयोग करने की आवश्यकता नहीं है।

सभी कार्यों से पहले उस पर एक वस्तु कतार एक धागा द्वारा किया जाता एक BlockingQueue "होने से पहले" वस्तु dequeued है। इसका मतलब है कि पहले धागे द्वारा किए गए कोई भी बदलाव दूसरे के लिए दृश्यमान होते हैं। समवर्ती संग्रह के लिए यह सामान्य व्यवहार है। the BlockingQueue class documentation.

का अंतिम पैराग्राफ देखें जब तक कि पहला धागा ऑब्जेक्ट को कतारबद्ध करने के बाद कोई संशोधन नहीं करता है, यह सुरक्षित रहेगा।

+2

+1। – Darron

2

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

लेकिन, आप सुनिश्चित कर सकते हैं कि सिंक्रनाइज़ कीवर्ड का उपयोग करके:

Message myMessage = // ... 
synchronized (myMessage) { 
    // You're the only one to have access to this instance, do what you want 
} 
: हर बार जब आप इस वस्तु का उपयोग करें और सुनिश्चित करें कि कोई अन्य धागा एक ही उदाहरण उपयोग कर रहा है, एक तुल्यकालन ब्लॉक में आप कोड लपेट होना चाहता हूँ

सिंक्रनाइज़ ब्लॉक MyMessage ऑब्जेक्ट पर एक निहित लॉक प्राप्त करेगा। इसलिए, जब तक आप इस ब्लॉक को छोड़ नहीं देते हैं, तब तक कोई अन्य सिंक्रनाइज़ ब्लॉक उसी ईवेंट तक पहुंच नहीं पाएगा।

+0

व्यक्ति getters और setters सिंक्रनाइज़ किया जा रहा वास्तव में कुछ साबित नहीं होता है दो धागे वास्तव में वस्तु पर बिछा रहे थे, तो। वे अभी भी असंगत राज्यों में आंशिक ओवरराइट्स देखेंगे। यह जवाब समस्या का समाधान करने का बेहतर तरीका है। – Affe

+0

@Vivien_Barousse इसलिए, मुझे वास्तव में कुछ भी सिंक्रनाइज़ करने की आवश्यकता नहीं है क्योंकि समवर्ती रूप से उपयोग नहीं किया जाएगा। यह मेरे प्रश्न का उत्तर देता है, धन्यवाद! –

3

आपको सिंक्रनाइज़ेशन स्वयं करने की आवश्यकता नहीं है, क्योंकि कतार आपके लिए पहले से ही है।

दृश्यता भी गारंटीकृत है।

0

ऐसा लगता है जैसे आप विधियों को सिंक्रनाइज़ कर सकते हैं। सिंक्रनाइज़ बस ऑब्जेक्ट को ताला लगा देता है ताकि केवल एक थ्रेड को एक्सेस किया जा सके। आप पहले ही ब्लॉकिंग कतार के साथ इसे संभाला है।

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

+0

'ब्लॉकिंग क्यूयू' के साथ 'अस्थिर' का उपयोग करना अनावश्यक है (और प्रयास का एक अक्षम डुप्लिकेशंस); 'BlockingQueue' अनुबंध का हिस्सा यह है कि किसी ऑब्जेक्ट को" किसी भी थ्रेड से पहले "ऑब्जेक्ट को एनक्यू करने से पहले किसी भी थ्रेड द्वारा किसी भी थ्रेड द्वारा निकाला जाता है। – erickson

+0

जानना अच्छा है। मुझे पता था कि अस्थिरता की आवश्यकता थी जब एक और धागा किसी क्षेत्र के मूल्य को बदल देता है। यह समझ में आता है कि थ्रेड अवरुद्ध उस पर ध्यान रखेगा, क्योंकि वर्तमान धागे मूल्य का अनुरोध करता है। BlockingQueue की थ्रेड दृश्यता अर्थशास्त्र का उल्लेख करने के लिए – tylermac

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

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