2015-08-22 9 views
5

द्वारा समवर्ती सरणी पहुंच श्रमिकों के बीच सरणी तत्वों को सही ढंग से प्रकाशित किया गया है?निष्पादक सेवा

मान लीजिए मैं एक बड़े सरणी है (किसी भी परमाणु डेटा प्रकार का है, इसलिए नहीं long या double),

  • मैं एक कार्यकर्ता कि सरणी है कि मैं यह है contructor के पास भरता है,
  • मैं प्रस्तुत बनाने एक निष्पादक के लिए कार्यकर्ता, और पूरा होने तक प्रतीक्षा करें (उदाहरणfuture.get() के साथ)। कार्यकर्ता कुछ भी वापस नहीं करता है। यह सिर्फ मेरी सरणी भरता है।
  • फिर, मैं तुरंत अपने निर्माता के समान सरणी के साथ एक और कार्यकर्ता जमा करता हूं और सबमिट करता हूं। क्या यह नवीनतम मूल्य देखता है?

दूसरे शब्दों में, यह गारंटी है कि पिछले कार्यकर्ता के पहले पढ़ने से पहले पिछले कार्यकर्ता का अंतिम लेखन होता है?

क्या मुझे इसके बजाय (या सर्वोत्तम अभ्यास या कुछ के लिए) पहले कार्यकर्ता को सरणी वापस करने दें, भले ही संदर्भ मेरे जैसा पहले से ही जैसा हो?

[संपादित करें] कुछ पृष्ठभूमि: मैं byte सरणी या short सरणी का उपयोग करता हूं, जो छवियों का प्रतिनिधित्व करते हैं और प्रत्येक 500,000,000 तत्वों का उपयोग करते हैं। मैं प्रत्येक तत्व पर सरल अंकगणित प्रदर्शन करता हूं।

+0

ऐसा लगता है कि आप ऐसा कुछ कर रहे हैं जो क्यूचर संरचना के साथ बेहतर काम करेगा जैसे ConcurrentLinkedQueue। –

+0

यह एक फीफो नहीं है। दूसरे कार्यकर्ता को सरणी में यादृच्छिक पहुंच की आवश्यकता होती है। –

+0

मुझे कुछ ट्यूटोरियल में ऐसा कुछ मिला: http://www.ibm.com/developerworks/library/j-jtp03304/jsr133.gif लेकिन मुझे यकीन नहीं है कि वैश्विक चर के मामले में इसकी व्याख्या कैसे करें। क्या सबकुछ * आंतरिक थैम में सिंक हो गया है जब थ्रेड अनलॉक हो और दूसरा ताला लगा हो? क्या निष्पादक आंतरिक रूप से इस तरह लॉक कर रहा है और न ही? –

उत्तर

3

package java.util.concurrent JavaDoc से उपयोग कर सकते हैं: java.util.concurrent में

सभी वर्गों के तरीकों और उसके सबपैकेज इन गारंटियों का विस्तार उच्च स्तरीय सिंक्रनाइज़ेशन के लिए। विशेष रूप से:

एसिंक्रोनस गणना द्वारा ली गई कार्रवाइयां भविष्य के द्वारा किए गए कार्यों से पहले की घटनाओं को Future.get() के माध्यम से किसी अन्य धागे में पुनर्प्राप्त करने के बाद होती है।

निष्पादक के लिए एक रननेबल जमा करने से पहले एक थ्रेड में क्रियाएं होती हैं-इससे पहले कि उसके निष्पादन शुरू हो जाएं। इसी प्रकार एक निष्पादक सेवा के लिए प्रस्तुत कॉलबल्स के लिए।

इसके अनुसार यह आपके परिदृश्य में दूसरे कार्यकर्ता से किसी सरणी तक पहुंचने के लिए बहुत सुरक्षित लगता है।

+0

मैंने भविष्य में प्रतिनिधित्व किए गए कार्य द्वारा किए गए कार्यों को पढ़ा है- फ्यूचर.जेट से दूसरे थ्रेड रिटर्न से पहले- 'अभ्यास में जावा कंसुरेंसी में पी344 (गोएट्ज़ एट अल 2006) और सोचा कि मैं अपने प्रश्न का उत्तर दूंगा, लेकिन मैं किसी भी तरह तुम्हारा याद किया होगा। –

2

सरणी के तत्व volatile नहीं हैं, इसलिए उन्हें सीपीयू द्वारा प्रति-थ्रेड कैश किया जा सकता है। इसलिए पहले कार्यकर्ता के लिए कुछ सरणी तत्व शुरू करना संभव है, लेकिन दूसरे कार्यकर्ता के लिए इसे कैशिंग के कारण नहीं देखना है।

सुनिश्चित करें कि सरणी तत्व खुद को परमाणु कर रहे हैं बनाने के लिए, आप एक AtomicReferenceArray

+0

प्रदर्शन के बारे में क्या? जब मैंने पहले श्रमिकों को आवंटित करने और एक नई सरणी वापस करने के लिए बदल दिया, और मुख्य धागे में मूल पर सरणी की प्रतिलिपि बनाई, तो यह समानांतर में 8 श्रमिकों के साथ 3 गुना धीमा हो गया। –

+0

AtomicReferenceArray के साथ क्या गलत है? – Malt

+0

समस्याओं में से एक स्मृति है। 'लघु' सरणी के साथ, मेरा प्रोग्राम दो 1 जीआईबी सरणी का उपयोग करता है। 'Int' arrays के साथ, मुझे' OutOfMemoryError' मिलता है (यहां तक ​​कि '-Xmx8G' के साथ)। मैंने अभी 'एटमिक रिफरेंसएरे' का प्रोफाइल किया है, और यह प्रति तत्व ~ 4.7 बाइट्स का उपयोग करता है। अगला, प्रदर्शन। प्रसंस्करण 'बाइट' सरणी मुझे ~ 640ms लेता है। प्रसंस्करण 'लघु' सरणी मुझे ~ 1100ms लेता है। मैं इसे 'एटमिक रिफरेंसएरे' के साथ भी परीक्षण करने वाला नहीं हूं जो लगातार बक्से/अनबॉक्स हैं। –

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