2011-01-26 22 views
5

ब्रायन गोएट्ज ने http://www.ibm.com/developerworks/java/library/j-jtp03048.html पर कांटा-जुड़ने पर एक अच्छा लेख लिखा। इसमें, वह फोर्क-जॉइन मैकेनिज्म का उपयोग करके मर्ज सॉर्ट एल्गोरिदम सूचीबद्ध करता है, जिसमें वह समानांतर में सरणी के दो किनारों पर सॉर्ट करता है, फिर परिणाम विलीन करता है।फोर्क में शामिल होने की मेमोरी दृश्यता

एल्गोरिदम एक ही सरणी के दो अलग-अलग वर्गों पर एक साथ टाइप करता है। एक परमाणु इंटेगरएरे या दृश्यता बनाए रखने के लिए आवश्यक कुछ अन्य तंत्र क्यों नहीं है? क्या गारंटी है कि एक धागा दूसरे द्वारा किए गए लेखन देखेगा, या यह एक छोटी सी बग है? फॉलो अप के रूप में, क्या स्कैला के फोर्कजोइन शेड्यूलर भी यह गारंटी देते हैं?

धन्यवाद!

+0

वे सरणी के विभिन्न वर्गों पर काम कर रहे हैं। विलय करने की बात आने तक कोई विवाद नहीं है। –

+3

मैं मानता हूं कि वे विभिन्न वर्गों पर काम कर रहे हैं। लेकिन जावा के मेमोरी मॉडल के अर्थशास्त्र कम या ज्यादा कहते हैं कि सभी धागे सभी लिखने की गारंटी नहीं देते हैं (जब तक वेरिएबल अस्थिर नहीं होता)। इस ब्लॉग के मुताबिक: http://jeremymanson.blogspot.com/2009/06/volatile-arrays-in-java.html यहां तक ​​कि एक अस्थिर int [] का उपयोग करने के लिए यह गारंटी देने के लिए पर्याप्त नहीं है कि अन्य धागे आपके लिखने को सरणी में देखें –

उत्तर

5

जॉइन (फोर्कजॉइन के) में स्वयं को एक सिंक्रनाइज़ेशन पॉइंट की आवश्यकता होती है, जो सूचना का सबसे महत्वपूर्ण हिस्सा है। एक सिंक्रनाइज़ेशन पॉइंट यह सुनिश्चित करेगा कि सभी लिखते हैं जो कहा गया बिंदु के बाद दिखाई दे रहे हैं।

यदि आप कोड को देखते हैं तो आप देख सकते हैं कि सिंक्रनाइज़ेशन बिंदु कहां होता है। यह सिर्फ एक विधि कॉल invokeAll किसी अन्य प्रक्रिया में

public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) { 
    t2.fork(); 
    t1.invoke(); 
    t2.join(); 
} 

यहाँ t2 कांटे है, t1 अपने कार्य को निष्पादित करता है और कि धागा बुला t2.join पर इंतजार करेंगे()। टी 2 पास करते समय। टी 1 और टी 2 के लिए सभी लिखते हैं तो दिखाई देंगे।

संपादित करें: यह संपादन सिंक्रनाइज़ेशन बिंदु से मेरा मतलब क्या है इसका एक स्पष्टीकरण देने के लिए बस कुछ और देना है।

कहना देता है जिन्हें आप दो चर

int x; 
volatile int y; 

किसी भी समय आप y के सभी लिखते हैं कि क्या हुआ इससे पहले कि आप पढ़ y उपलब्ध हो जाएगा बारे में है। उदाहरण

public void doWork(){ 
    x = 10; 
    y = 5; 
} 

के लिए एक और धागा पढ़ता है तो y = 5 धागा गारंटी क्योंकि y लिखने एक तुल्यकालन बिंदु जिसमें सभी लेखन से पहले कहा बिंदु हो जाएगा बनाता है एक्स = 10 यह वह जगह है पढ़ने के लिए है कि लिखने के बाद दिखाई देता है।

फोर्क जुड़ें पूल के साथ फोर्कजोइन टास्क में शामिल होने से सिंक्रनाइज़ेशन पॉइंट बन जाएगा। अब अगर t2.fork() और t1.invoke() टी 2 में शामिल होने से यह सुनिश्चित होगा कि पहले लिखा गया था कि सभी लिखेंगे। चूंकि सभी पिछले लेखन एक ही संरचना के भीतर हैं, यह दृश्यता के लिए सुरक्षित होगा।

अगर मुझे स्पष्ट नहीं है तो मुझे आगे बताने में खुशी होगी।

+0

'coInvoke' द्वारा बुलाया गया 'invokeAll' है? –

+0

और, केवल उत्तर के पूरक के लिए, http://java.sun.com/docs/books/jls/third_edition/html/memory.html#64058 भी देखें। –

+0

@ डैनसील सी सोब्राल दिलचस्प आप पूछते हैं, जब मैं इस उदाहरण को लिख रहा था तो मैं वास्तव में coInvoke विधि की तलाश में था। ऐसा लगता है कि coInvoke विधि स्वयं स्रोत कोड से शुद्ध कर दिया गया है। कम से कम मुझे अब यह नहीं मिल रहा है। –

1

बस एक अनुमान: विलय में थ्रेड पर शामिल होना शामिल है, और शामिल होने से दृश्यता की गारंटी मिलती है।

दूसरा भाग निश्चित है; मुझे नहीं पता कि मर्ज लागू कैसे किया जाता है।

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