2012-06-22 6 views
9

बाइटबफर थ्रेड को सुरक्षित करने के लिए मुझे क्या विकल्प चाहिए? यह ज्ञात है कि यह थ्रेड सुरक्षित नहीं है क्योंकि यह सुरक्षित स्थिति, सीमा और कुछ (/ सभी?) विधियां इस आंतरिक स्थिति पर निर्भर करती हैं।जावा के बाइटबफर थ्रेड को सुरक्षित बनाने के विकल्प

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

क्या मैं मन में है:

  • सिंक्रनाइज़ करना या सभी तरीकों के लिए ReadWrite ताले का उपयोग कर। शायद सबसे धीमी दृष्टिकोण (?)
  • बाइटबफर को उप-वर्गीकृत करना और स्थायी थ्रेड-बाउंड स्थिति जैसे स्थिति आदि से बचें और आंतरिक विधियों का उपयोग करने के लिए आवश्यक सभी विधियों के अनुसार अपवाद फेंकना। यह उपवास होगा। लेकिन क्या कोई जाल है? (सिवाय इसके कि मुझे सीधे मैप मेमोरी में हेप मेमोरी में पढ़ना होगा ...)

मैं अन्य चाल का उपयोग कैसे कर सकता हूं? मैं कैसे उदाहरणूँगा डायरेक्टबफर के साथ "पढ़ने पर क्लोन बाइट्स" को लागू करें - क्या यह संभव है? शायद एक पूर्ण समाधान में पूर्ण ByteBuffer (ByteBuffer.slice) को टुकड़ा करना होगा?

अद्यतन: क्या के साथ इस question में मतलब है "नकल (जबकि सिंक्रनाइज़) एक नया उदाहरण एक ही मैप किया बाइट्स की ओर इशारा करते प्राप्त करने के लिए"

+1

मैं एक अभिनेता मॉडल का उपयोग करना पसंद करता हूं जहां कोई बाइटबफर केवल एक थ्रेड द्वारा अपडेट किया जाता है (या केवल पढ़ा जाता है)। कारण यह है कि मैंने पाया है कि सिंक्रनाइज़ेशन का ओवरहेड आम तौर पर एकाधिक धागे होने के लाभों से अधिक है। –

+0

धन्यवाद, पीटर! क्या आप टुकड़ा के माध्यम से इसका उपयोग कर रहे हैं? या आप एक ही डेटा तक कैसे पहुंचते हैं? – Karussell

+0

मैं एक टुकड़ा का उपयोग नहीं करता, इसके बजाय मैं एक रैपर का उपयोग करता हूं जो सबकुछ छुपाता है (यहां तक ​​कि तथ्य मैं बाइटबफर का उपयोग कर रहा हूं और मैं असुरफ पर स्विच करना चाहता हूं जो थोड़ा तेज़ है) एक रैपर का उपयोग करने का लाभ यह है कि आप सभी को छुपा सकते हैं विवरणों को कॉल करके स्वाभाविक रूप से विवरणों और अपने "सरणी" तक पहुंचें। यह विशेष रूप से उपयोगी है क्योंकि मेरे पास अरबों तत्वों के साथ सरणी हैं जो एक बाइटबफर में फिट नहीं होंगे। –

उत्तर

11

एक बफर वर्ग बनाया जा सकता है धागा सुरक्षित ... इस अर्थ में कि व्यक्तिगत संचालन ठीक से सिंक्रनाइज़ किए गए थे, आदि। हालांकि, एपीआई को कई धागे के साथ दिमाग में डिजाइन नहीं किया गया है, इसलिए यह शायद समय की बर्बादी है।

मूल समस्या यह है कि एक बफर पर व्यक्तिगत संचालन सिंक्रनाइज़ेशन की इकाई होने के लिए बहुत बढ़िया होते हैं। एक आवेदन प्राप्त करने और संचालन, या फ्लिप, स्थिति आदि के स्तर पर अर्थपूर्ण रूप से सिंक्रनाइज़ नहीं कर सकता है। आम तौर पर, एक आवेदन को प्रभावशाली ढंग से सिंक्रनाइज़ करने के लिए परमाणु रूप से इन परिचालनों के अनुक्रमों को करने की आवश्यकता होती है।

दूसरी समस्या यह है कि यदि आप एक अच्छे स्तर पर सिंक्रनाइज़ करते हैं, तो यह विधि कॉल पर महत्वपूर्ण ओवरहेड जोड़ने की संभावना है। चूंकि बफर एपीआई का उपयोग करने का बिंदु I/O कुशलतापूर्वक करना है, यह उद्देश्य को हरा देता है।


आप एक साझा बफर करने के लिए धागा पहुँच सिंक्रनाइज़ करने की आवश्यकता है, तो इसमें बाहरी तुल्यकालन उपयोग करने के लिए बेहतर है; जैसे कुछ इस तरह:

synchronized (someLock) { 
     buffer.getByte(); 
     buffer.getLong(); 
     ... 
    } 

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


के रूप में टिप्पणी का कहना है, आप भी ByteBuffer.slice() या buffer.asReadOnlyBuffer() का उपयोग समर्थन के रूप में मौजूदा एक के साथ आप एक और बफर देने के लिए कर सकता है। हालांकि, javadocs किसी भी मामले में थ्रेड-सुरक्षा की गारंटी नहीं देता है।

बफ़र कई समवर्ती धागे द्वारा उपयोग के लिए सुरक्षित नहीं हैं: दरअसल, Buffer के लिए javadocs इस कंबल बयान। यदि एक बफर का उपयोग एक से अधिक धागे से किया जाना है तो बफर तक पहुंच उचित सिंक्रनाइज़ेशन द्वारा नियंत्रित की जानी चाहिए।

+0

क्या आप केवल पढ़ने के लिए बफर केस पर टिप्पणी करेंगे? – Karussell

+0

मुझे नहीं लगता कि केवल पढ़ने के मामले में चीजों को सरल बनाता है , जब तक कि आप बफर को एक साधारण सरणी के रूप में इलाज करने के लिए तैयार नहीं होते हैं ... 'सरणी()' के माध्यम से सीधे बैकिंग सरणी का उपयोग करें और उपयोग करें। फिर भी आपको स्मृति को लगातार एक्सेस करने के लिए कुछ सिंक्रनाइज़ेशन की आवश्यकता होती है। –

+1

यह असंगत कैसे हो सकता है कोई लेखन नहीं होता है? बैकिंग सरणी हमेशा मौजूद नहीं होती – Karussell

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