2011-08-27 32 views
48

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

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

मैं स्विंग का उपयोग कर रहा हूं और जहां तक ​​मैं विस्तार से इसका मतलब इकट्ठा कर सकता हूं, मैं भी एडब्ल्यूटी का उपयोग कर रहा हूं।

मेरा प्रश्न कोड के इस टुकड़े पर आधारित है:

java.awt.EventQueue.invokeLater(new Runnable() { 
    public void run() { 
     new frame.setVisible(true); 
    } 
}); 

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

मैंने पढ़ा है कि:

और केवल के तहत कुछ निश्चित परिस्थितियों आप तरीकों कॉल कर सकते हैं कि "आप केवल तरीकों कि घटना भेजने थ्रेड से फ्रेम पर काम कॉल कर सकते हैं" कि मुख्य विधि से फ्रेम पर काम करते हैं।

क्या कोई मुझे स्पष्ट कर सकता है कि इवेंट-डिस्पैचिंग थ्रेड वास्तव में क्या है?

यह निष्पादन के कई धागे से कैसे संबंधित है और यह थ्रेड मुख्य विधि से कैसे सुरक्षित नहीं हैं? इसके अलावा हमें इस invokeLater की आवश्यकता क्यों है?

क्या हम खिड़की को किसी अन्य वस्तु के रूप में नहीं बना सकते हैं?

मैंने अपने शोध में एक सड़क ब्लॉक को थोड़ा सा मारा है क्योंकि मैं इन संबंधों और विचारों को समझ नहीं रहा हूं।

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

धन्यवाद।

उत्तर

54

इवेंटडिस्चिंग थ्रेड एक विशेष धागा है जिसे एडब्ल्यूटी द्वारा प्रबंधित किया जाता है। असल में यह एक धागा है जो एक अनंत लूप प्रसंस्करण घटना में चलता है। Java.awt.EventQueue.invokeLater विधि कुछ कोड प्रदान करने का एक विशेष तरीका है जो ईवेंट कतार पर चलाएगा। एक मल्टीथ्रेडिंग वातावरण में सुरक्षित एक यूई फ्रेमवर्क लिखना बहुत मुश्किल है इसलिए एडब्ल्यूटी लेखकों ने फैसला किया कि वे केवल एक विशेष थ्रेड पर होने वाली जीयूआई वस्तुओं पर संचालन की अनुमति देंगे। सभी ईवेंट हैंडलर इस थ्रेड पर निष्पादित करेंगे और गुई को संशोधित करने वाले सभी कोड को भी इस धागे पर संचालित करना चाहिए।

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

तो एक क्लासिक उदाहरण यह है कि आपको फ़ाइल डाउनलोड करने जैसे लंबे समय तक चलने वाले ऑपरेशन को चलाने की आवश्यकता है। तो जब आप इसे पूरा कर लेंगे तो इस क्रिया को करने के लिए आप एक थ्रेड लॉन्च करेंगे, आप UI को अपडेट करने के लिए invokeLater का उपयोग करेंगे। यदि आपने invokeLater का उपयोग नहीं किया है और इसके बजाय आपने सीधे यूई को अपडेट किया है तो आपके पास दौड़ की स्थिति हो सकती है और अपरिभाषित व्यवहार हो सकता है। http://en.wikipedia.org/wiki/Event_dispatching_thread

इसके अलावा, अगर आप उत्सुक हैं, जिनके चलते AWT लेखकों सिर्फ टूलकिट यहाँ थ्रेड नहीं बनाते हैं एक अच्छा लेख है:

विकिपीडिया में अधिक जानकारी है https://community.oracle.com/blogs/kgh/2004/10/19/multithreaded-toolkits-failed-dream

+0

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

+1

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

+0

ठीक है, यह समझ में आता है, बहुत बहुत धन्यवाद। आपने मेरे लिए कुछ विसंगतियों को मंजूरी दे दी है। – linuscash

11

EventDispatchThread (EDT) विशेष धागा आरक्षित है केवल स्विंग जीयूआई और * स्विंग के संबंधित कार्यक्रमों के लिए उदाहरण के लिए/बनाने परिवर्तन/अद्यतन Swing JComponents, अधिक पूछे जाने वाले प्रश्नों के लिए here और here

BackGround Tasks से जीयूआई करने के लिए सभी उत्पादन, Runnable#ThreadinvokeLater() में, सिंक्रनाइज़ वस्तुओं से invokeAndWait();

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

  • कोई संबंधित समस्या नहीं^_^