2010-03-20 18 views
6

मुझे पता है कि "थ्रेड" का अर्थ क्या है और यदि मैं "केवल एक थ्रेड" के रूप में ईवेंट प्रेषण थ्रेड (ईडीटी) को समझता हूं, तो यह बहुत समझाता है, लेकिन जाहिर है, यह सबकुछ समझाता नहीं है।घटना प्रेषण धागा क्या है?

मुझे समझ में नहीं आता कि इस धागे के बारे में क्या विशेष है। उदाहरण के लिए मुझे समझ में नहीं आता कि हमें ईडीटी में जीयूआई क्यों शुरू करना चाहिए? GUI के लिए "मुख्य" धागा बिस्तर क्यों है? खैर, अगर हम मुख्य धागे पर कब्जा नहीं करना चाहते हैं तो हम "अन्य धागे" में जीयूआई क्यों शुरू नहीं कर सकते हैं, यह ईडीटी नामक कुछ "विशेष" धागा क्यों होना चाहिए?

तब मुझे समझ में नहीं आता कि हम ईडीटी को किसी अन्य थ्रेड की तरह क्यों शुरू नहीं कर सकते? हमें कुछ विशेष उपकरण का उपयोग क्यों करना चाहिए (invokeLater कहा जाता है)। और क्यों जीयूआई, किसी अन्य धागे के विपरीत, तुरंत शुरू नहीं होता है। हमें तब तक इंतजार करना चाहिए जब तक कि यह हमारी नौकरी स्वीकार करने के लिए तैयार न हो। क्या ऐसा इसलिए है क्योंकि ईडीटी संभावित रूप से कई कार्यों को निष्पादित कर सकता है?

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

जोड़ा:

मैं हमेशा सोचा कि हम धागा प्रति एक "काम" है। तो, प्रत्येक धागे में हम आदेशों का एक पूर्वनिर्धारित अनुक्रम निष्पादित करते हैं। लेकिन मुझे ऐसा लगता है कि घटना में धागे को प्रेषित करने में हम अलग कार्य कर सकते हैं। खैर, वे एक साथ निष्पादित नहीं होते हैं (विभिन्न कार्यों के बीच थ्रेड स्विच लेकिन एक थ्रेड में अभी भी कई कार्य हैं)। क्या यह सही है? उदाहरण के लिए ईडीटी में एक धागा है जो मुख्य विंडो प्रदर्शित करता है, और उसके बाद हमने ईडीटी को एक और कार्य भेजा है जो विंडो घटकों में से एक को अपडेट करना चाहिए और ईडीटी जब भी तैयार हो, तो इस नए कार्य को निष्पादित करेगा। क्या ईडीटी इस तरह से अन्य धागे से अलग है?

+0

ईडीटी एक दूसरे के समान ही धागा है। जावा में प्रत्येक थ्रेड के लिए एक कार्य है, इसे 'टी' में पारित एक 'रननेबल' के रूप में व्यक्त किया जाता है। ह्रेड' या एक 'रन()' विधि। हालांकि, थ्रेड के लिए इस तरह के कार्य की कल्पना करें: कतार पर प्रतीक्षा करें और प्रत्येक कतार ('रननेबल') को निष्पादित करें जो मेरी कतार में जोड़ा गया है? यह इस तरह काम करता है। – pajton

उत्तर

6

घटना प्रेषण धागा वह थ्रेड है जो सभी जीयूआई घटनाओं को संभालता है और आपके स्विंग जीयूआई का प्रबंधन करता है। यदि आपके प्रोग्राम में कोई GUI है तो यह स्विंग कोड में कहीं भी शुरू किया गया है। दृश्यों के पीछे किया जाने वाला कारण सादगी के कारण है - आपको अपने द्वारा अतिरिक्त धागे को शुरू करने और प्रबंधित करने से परेशान नहीं होना चाहिए।

इस तथ्य के संबंध में कि आपको invokeLater() के साथ अपना जीयूआई अपडेट करना है, यह समवर्ती मुद्दों के कारण है। जीयूआई को केवल एक थ्रेड से संशोधित किया जा सकता है क्योंकि स्विंग थ्रेड सुरक्षित नहीं है (यह ध्यान देने योग्य है कि टूलकिट्स के अधिकांश थ्रेड सुरक्षित नहीं हैं, nice article है जो कुछ विचार देता है)। यही कारण है कि आपको ईडीटी पर चलाने के लिए सभी जीयूआई अपडेट जमा करना होगा।

आप Sun tutorial on concurrency in Swing में स्विंग और इवेंट प्रेषण धागे में समवर्तीता पर और अधिक पढ़ सकते हैं। साथ ही, यदि आप देखना चाहते हैं कि यह अलग तरीके से कैसे किया जा सकता है तो आप SWT toolkit को देखना चाहेंगे। एसडब्ल्यूटी में आपको अपने द्वारा ईडीटी का प्रबंधन करना होगा।

3
What is the EDT? 

यह महान कई संगामिति मुद्दों घुमाओ एपीआई है कि चारों ओर एक hacky वैकल्पिक हल है;)

गंभीरता से, स्विंग घटकों का एक बहुत नहीं "धागा सुरक्षित" (कुछ प्रसिद्ध प्रोग्रामर के रूप में अब तक बुला के रूप में चला गया कर रहे हैं स्विंग "थ्रेड शत्रुतापूर्ण")। एक अद्वितीय धागा होने के साथ जहां इस धागे-विरोधी घटकों के लिए सभी अपडेट किए जाते हैं, आप बहुत सारे संभावित समवर्ती मुद्दों को हल कर रहे हैं। इसके अलावा, आपको यह भी गारंटी दी जाती है कि यह रननेबल को चलाएगा जिसे आप अनुक्रमिक क्रम में invokeLater का उपयोग करके पार करते हैं।

ध्यान दें कि यह सिर्फ है कि आप संगामिति मुद्दा dodging रहे हैं नहीं है: आप के बारे में क्या है और क्या EDT पर नहीं किया जाना चाहिए चाहिए या आप अपने आवेदन में गंभीर समस्याओं का होगा सूर्य के दिशा निर्देशों का सम्मान करना चाहिए।

एक और लाभ यह है कि कुछ स्विंग घटक अवांछित अपवाद फेंकते हैं और जब ऐसा होता है तो वे स्वचालित रूप से निपटाए जाते हैं और ईडीटी को क्रैश नहीं करेंगे (AFAIK यदि आप वास्तव में ईडीटी को मारने का प्रबंधन करते हैं तो यह स्वचालित रूप से पुनरारंभ होता है)।

दूसरे शब्दों में: आपको सभी टूटे हुए स्विंग घटकों और उनके द्वारा फेंकने वाले अपवादों से निपटने की ज़रूरत नहीं है: ईडीटी इसका ख्याल रखता है (केवल अनगिनत स्विंग बग पर एक नज़र डालें जो सूर्य की बग में अपवाद फेंक रहा है परेड, यह आकर्षक है ... और फिर भी अधिकांश ऐप्स सामान्य रूप से काम करते रहते हैं)।

इसके अलावा, केवल ईडीटी में अनिवार्य है जो आपके ऐप के जीयूआई को "उत्तरदायी" रहने के लिए भी कठिन बनाता है, वहां पृष्ठभूमि में कार्य हो सकते हैं।

3

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

तो समाधान: केवल एक थ्रेड से स्विंग विधियों को कॉल करें। यह ईडीटी थ्रेड है - यह किसी अन्य तरीके से विशेष नहीं है, इसके अलावा यह स्विंग विधियों को कॉल करने के लिए नामित थ्रेड है।

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

+0

@amarillion: ईडीटी में होने वाले अपवादों में यह कुछ खास बात है कि अन्य धागे में अपवादों से अलग व्यवहार कर रहे हैं और आपको ईडीटी को मारना चाहिए, यह स्वचालित रूप से फिर से शुरू हो जाता है। – SyntaxT3rr0r

+0

ठीक है। यह एक व्यावहारिक समाधान के रूप में मुझे लगता है। इसलिए, मैंने अपना जीयूआई एप्लीकेशन ईडीटी ('invokeLater' का उपयोग करके) में रखा और फिर, यदि मेरे पास कई अन्य धागे हैं, और मैं इन थ्रेड से जीयूआई एप्लीकेशन को कॉल करना चाहता हूं, तो मैं इन कॉल को' invokeLater' का उपयोग करके कर दूंगा और सब कुछ चाहिए ठीक रहो। क्या यह इस तरह से काम करता है? – Roman

+0

@ रोमन: बिल्कुल। लेकिन एक साधारण एप्लिकेशन के लिए, जहां आप कार्रवाई में सभी काम करते हैं लिस्टेनर्स और अन्य ईवेंट हैंडलर, मुख्य() वास्तव में एकमात्र तरीका हो सकता है जो ईडीटी पर नहीं है। तो आप केवल एक बार invokeLater बुलाओ। बेशक यह सरल अनुप्रयोगों के लिए केवल सच है, लेकिन जावा के साथ शुरू करने के लिए यह जानना पर्याप्त है। – amarillion

6

मैंने हमेशा सोचा कि हमारे पास प्रति "कार्य" है। तो, प्रत्येक थ्रेड में हम कमांड के पूर्वनिर्धारित अनुक्रम निष्पादित करते हैं। लेकिन मुझे लगता है कि में घटना प्रेषण धागा हम से अलग कार्य कर सकते हैं। खैर, वे एक साथ निष्पादित नहीं हैं (थ्रेड विभिन्न कार्यों के बीच स्विच लेकिन अभी भी थ्रेड में कई कार्य हैं)। क्या यह सही है? उदाहरण के लिए वहाँ EDT जो मुख्य विंडो प्रदर्शित में एक धागा, और फिर यह है कि हम EDT को किसी अन्य कार्य जो खिड़की घटकों के एक अद्यतन करना चाहिए और EDT जब भी यह इस नए कार्य को निष्पादित करेंगे भेजा अतिरिक्त है तैयार है। क्या ईडीटी इस तरह से अन्य धागे से अलग है?

नहीं, ईडीटी मूल रूप से अन्य धागे से अलग नहीं है। और "कार्य" उपयोग करने के लिए एक अच्छा शब्द नहीं है, क्योंकि इसे ओएस-स्तरीय प्रक्रियाओं (जिसे अक्सर कार्य कहा जाता है) के साथ भ्रमित किया जा सकता है। Runnable का बेहतर उपयोग, इंटरफ़ेस invokeLater() के माध्यम से निष्पादित करने के लिए ईडीटी को कोड देने के लिए उपयोग किया जाता है।

ईडीटी मूल रूप से उन चीजों की कतार से जुड़ा हुआ है जो इसे करना है। जब उपयोगकर्ता जीयूआई पर एक बटन पर क्लिक करता है, तो Runnable जो बटन से जुड़े सभी श्रोताओं को कतार में जाता है, को सूचित करता है। जब एक विंडो का आकार बदलता है, तो Runnable रीडालिडेट & पुनर्विक्रय कतार में जाता है। और जब आप invokeLater() का उपयोग करते हैं, तो आपकी Runnable कतार में जाती है।

EDT बस एक अंतहीन लूप कि कहते हैं, "पंक्ति से एक Runnable ले (और अगर यह खाली नींद है जब तक आप कैसे सूचित किया जाए कि यह नहीं है) और यह निष्पादित इस प्रकार चलाता है।

, यह उन सभी छोटी कार्यान्वित Runnable कोड के टुकड़े एक दूसरे के बाद, ताकि उनमें से प्रत्येक के पास मूल रूप से जीयूआई हो, जबकि यह चलता है, और किसी भी चीज को सिंक्रनाइज़ करने के बारे में चिंता करने की ज़रूरत नहीं है। जब आप जीयूआई को किसी अन्य धागे से जोड़ते हैं, तो यह धारणा टूट जाती है, और आप भ्रष्ट स्थिति में जीयूआई के साथ समाप्त कर सकते हैं।

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