2012-11-22 13 views
7

मैंने कई बार सुना है कि जावा स्विंग थ्रेडिंग मॉडल गलत है। मैं पूरी तरह से समझ में नहीं आता क्यों, मुझे पता है कि समस्या इस तथ्य से संबंधित है कि आप मुख्य यूआई थ्रेड के अलावा किसी अन्य धागे से Drawable पर आकर्षित कर सकते हैं। मुझे पता है कि SwingUtilities.invokeAndWait और SwingUtilities.invokeLater जैसी उपयोगिता कार्यक्षमताएं हैं जो आपको Runnable में अपनी पेंटिंग करने देती हैं, जो बदले में इवेंट डिस्पैचर थ्रेड द्वारा चलाया जाता है। मुझे लगता है कि इस तरह से आप सुनिश्चित करते हैं कि पेंटिंग समकालिक रूप से की जाती है और यह बफर को एक असंगत स्थिति में नहीं छोड़ती है।स्विंग थ्रेडिंग मॉडल को गलत क्यों माना जाता है और यह कैसे होना चाहिए?

मेरा प्रश्न है: "अच्छा" UI टूलकिट कैसे व्यवहार करता है? क्या समाधान अपनाए जाते हैं?

+0

मैं जानना चाहता हूं कि इस सवाल को कम क्यों करें ... इसके साथ क्या गलत है? – gotch4

+4

एक उपरोक्त है। मुझे लगता है कि आपका सवाल ठीक है। –

+2

हो सकता है कि आप उस संदर्भ को लिंक कर सकें जहां आपने यह सुना है? – Axel

उत्तर

9

ब्रायन गोएज़ के Java Concurrency in Practice,

9,1 क्यों GUIs हैं एकल पिरोया?:

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

+0

एक और सवाल हो सकता है, क्यों, एंड्रॉइड और invokeLater को आमंत्रित करने के बजाय, BEGIN_DRAW और END_DRAW विधियों की एक जोड़ी में ड्राइंग कॉल संलग्न करने वाले दृष्टिकोण का उपयोग न करने के लिए, ताकि वे समेकन का ख्याल रख सकें?मैंने इसे चारों ओर देखा है, उदाहरण के लिए ओजीएल में। – gotch4

+0

@ gotch4 उन विधियों में वास्तव में 'रननेबल' में कार्रवाइयों को शामिल करता है और उन्हें 'EventQueue' में पोस्ट करता है ताकि वे' EventDispatchThread' पर उपलब्ध हो जाएं। ये क्रियाएं ईडीटी में की जाती हैं। जब आप सुझाए गए तरीकों के साथ बेवकूफ सीमांकन का उपयोग करते हैं - उनके बीच जो भी हो जाता है, वह इस वर्तमान धागे (ईडीटी नहीं) में किया जाता है। –

0

स्विंग का एक धागा है जो मूल रूप से उपयोगकर्ता को आपके एप्लिकेशन के ग्राफ़िकल भाग से इंटरैक्ट करने देता है। यदि आप उपयोगकर्ता द्वारा शुरू की गई घटनाओं के जवाब में केवल त्वरित कार्य करते हैं, तो आपका आवेदन हमेशा उत्तरदायी होगा।

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

यदि आप एक अलग थ्रेड में कोई कार्य चला रहे हैं (उदाहरण के लिए, आप एक पृष्ठ डाउनलोड कर रहे हैं और आप उपयोगकर्ता को सूचित करना चाहते हैं कि डाउनलोड पूरा हो गया है), तो आप सीधे उस कार्य से स्विंग को अपडेट नहीं कर सकते आपको अपने प्रश्न में वर्णित सहायक तरीकों में से एक का उपयोग करना होगा।

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

+0

उत्तर के लिए धन्यवाद, लेकिन यह वह हिस्सा है जिसे मैं कम या ज्यादा जानता था :) मैं जानना चाहता हूं कि अन्य UI सिस्टमों में समस्या का समाधान कैसे किया जाता है – gotch4

+0

@ gotch4 वे इसे अलग से अलग नहीं करते हैं। वे उन सभी की तरह काम करते हैं। – nos

1

वर्तमान प्रदर्शन प्रौद्योगिकियों को लागू करने के तरीके, स्क्रीन पर पेंटिंग पिक्सेल हमेशा धारावाहिक होता है। आपको लगभग 30 छवियों को एक सेकंड उत्पन्न करने की आवश्यकता है, और उन्हें एक-एक करके पेंट करना होगा।

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

तो तकनीकी रूप से, स्विंग थ्रेड-सुरक्षित है, अगर आप परिवर्तन सबमिट करने के लिए ईडीटी का उपयोग करते हैं। और यही invokeLater() और invokeAndWait() विधियों के लिए हैं। वे ईडीटी में परिवर्तन जमा करते हैं।

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

3

SWT के लिए: http://book.javanb.com/swt-the-standard-widget-toolkit/ch05lev1sec7.html

SWT एक एकल पिरोया यूजर इंटरफेस मॉडल है कि आम तौर फ्लैट सूत्रण कहा जाता है लागू करता है। इस मॉडल में, केवल उपयोगकर्ता इंटरफ़ेस थ्रेड उपयोगकर्ता इंटरफ़ेस संचालन का आह्वान कर सकता है। यह नियम सख्ती से लागू है। यदि आप उपयोगकर्ता इंटरफ़ेस थ्रेड के बाहर से एक SWT ऑब्जेक्ट तक पहुंचने का प्रयास करते हैं, तो आपको एक SWTException ("अमान्य थ्रेड एक्सेस") मिलेगा।

तो एसडब्ल्यूटी भी सिंगल-थ्रेडेड है। लेकिन यूआई थ्रेड के बाहर यूआई में किए गए किसी भी बदलाव को रोकने के लिए अतिरिक्त कदम उठाता है। स्विंग में विकल्प पर विचार करें जहां कहीं और से यूआई को संशोधित करने की अनुमति है, लेकिन जल्द या बाद में अप्रत्याशित परिणाम उत्पन्न करेगा जो नौसिखिया प्रोग्रामर को भ्रमित कर देगा जो तब सीखेंगे कि स्विंग "हार्ड" तरीके से सिंगल-थ्रेडेड है।

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

इसके अलावा, मैं अन्य कारणों की कल्पना नहीं कर सकता कि स्विंग के थ्रेडिंग मॉडल को "गलत" क्यों माना जाएगा।

+0

एसडब्ल्यूटी कैसे पता लगा सकता है कि यूआई के साथ एक और धागा गड़बड़ कर रहा है? क्या सभी टूलकिट विधियां प्रॉक्सी हुई हैं और एक चेक किया गया है? – gotch4

+0

मुझे यकीन नहीं है क्योंकि मैं SWT के साथ बहुत अनुभवी नहीं हूं, लेकिन जाहिर है, क्योंकि त्रुटि का स्टैक ट्रेस प्रॉक्सी नहीं दिखाता है और अपवाद दिखाता है कि उन तरीकों से उत्पन्न होता है जिनके नाम इंगित करते हैं कि वे कुछ की तरह जांच कर रहे हैं। eclipse.swt.widgets.Display.checkDevice। असल में सभी विधियां अपवाद नहीं फेंक देंगी। वे लोग जिन्हें ERTEOR_THREAD_INVALID_ACCESS मान के साथ SWTException फेंकने के अतिसंवेदनशील के रूप में दस्तावेज किया जाएगा। –

+0

यह जावाफैक्स के रूप में वैसे ही जांच सकता है या स्विंग करता है यदि आप [इस आलेख] में वर्णित कस्टम रिपेंट मैनेजर का उपयोग करते हैं (http://weblogs.java.net/blog/alexfromsun/archive/2006/02/ debugging_swing.html) – Robin

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