2010-08-23 15 views
40

SwingUtilities.invokeLater() में जीयूआई अपडेट कोड डालना क्यों आवश्यक है?SwingUtilities.invokeLater() इसकी आवश्यकता क्यों है?

इसे स्विंग द्वारा आंतरिक रूप से क्यों ख्याल रखा जा सकता है? कॉलर को इस बात की परवाह क्यों है कि स्विंग यूआई अपडेट कैसे संभालती है?

+1

असल में यह तरीका डेवलपर ** ** ** थ्रेड सिंक्रनाइज़ेशन के बारे में चिंता करने के लिए बिल्कुल नहीं है, क्योंकि आप बस स्विंग को यह बताते हैं कि यह अपडेट करने का समय है, और भारी काम दृश्यों के पीछे किया जाता है। – OscarRyz

उत्तर

35

स्विंग ऑब्जेक्ट्स are not thread safeSwingUtilities.invokeLater() कुछ समय बाद कार्य को निष्पादित करने की अनुमति देता है, जैसा कि नाम बताता है; लेकिन सबसे महत्वपूर्ण बात यह है कि कार्य एडब्ल्यूटी इवेंट प्रेषण धागे पर निष्पादित किया जाएगा। invokeLater का उपयोग करते समय, कार्य को असीमित रूप से निष्पादित किया जाता है; invokeAndWait भी है, जो तब तक वापस नहीं आएगा जब तक कार्य निष्पादित नहीं हो जाता है।

स्विंग धागा सुरक्षित बनाने के लिए नहीं करने का निर्णय बारे में कुछ जानकारी यहां पाया जा सकता: Multithreaded toolkits: A failed dream?

+2

स्विंग द्वारा आंतरिक रूप से देखभाल क्यों की जा सकती है? कॉलर को इस बात की परवाह क्यों है कि स्विंग यूआई अपडेट कैसे संभालती है? –

+4

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

14

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

अधिक यहाँ स्पष्टीकरण: http://www.oracle.com/technetwork/java/painting-140037.html

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

+1

ऐसा लगता है कि आपका लिंक टूटा हुआ है –

+1

@pavelrappo - ओरेकल ने उस लेख को हटा दिया जिसे मैं लिंक कर रहा था। मैंने एक ऐसा पाया जो अलग है, लेकिन इसमें कुछ स्पष्टीकरण भी शामिल है। –

2

SwingUtilities.invokeLater()

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

7

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

कहा जा रहा है कि आपको प्रत्येक यूआई ऑपरेशन को SwingUtilities.invokeLater() में लपेटने की आवश्यकता नहीं है - यदि आपके द्वारा लिखे गए कोड को ईडीटी द्वारा पहले ही निष्पादित किया गया है, तो इसकी आवश्यकता नहीं है। इसलिए बटन क्लिक के लिए ActionListener इसकी आवश्यकता नहीं है। लेकिन बाहरी ऑब्जेक्ट पर एक श्रोता, किसी अन्य थ्रेड में चल रहा है, जो कहीं भी JLabel अपडेट करता है - वहां आपको इसकी आवश्यकता है।

5

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

अधिक जानकारी के लिए जावा ट्यूटोरियल से Concurrent in Swing देखें। यह this ब्लॉग एंट्री का भी संदर्भ देता है कि मल्टीथ्रेडेड जीयूआई टूलकिट लिखना मुश्किल क्यों है।

3

घटकों की सभी पेंटिंग एक थ्रेड में निष्पादित की जानी चाहिए, इसलिए, उन्हें ठीक से प्रस्तुत किया जाता है। इस तरह घटक को पता चलेगा कि कौन सा हिस्सा पहले से ही चित्रित किया गया है और कौन सा हिस्सा नहीं है।

यदि आप ईडीटी के बाहर "पेंटिंग" संबंधित विधि (पेंट, अपडेट, पेंट कॉम्पोनेंट, शो, सेट विज़िबल, पैक इत्यादि) का आह्वान करते हैं, तो आप दो अलग-अलग धागे में पेंट करने की कोशिश करेंगे, और इससे समस्याएं आ सकती हैं।

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

आप एक विधि है कि पहले से ही EDT में चलाता है में कोडिंग कर रहे हैं तो आप इसका इस्तेमाल करने की जरूरत नहीं है (उदाहरण के लिए, actionPerformed या paint या उन में से एक) या फिर आप को क्रियान्वित कर रहे हैं कोड के लिए UI नहीं संबंधित (उदाहरण के लिए, पृष्ठभूमि आदि में प्रसंस्करण फ़ाइलें)

बेहतर समझने के लिए इन सभी अवधारणाओं पढ़ें: The single thread rule

1

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

स्विंग क्यों आंतरिक रूप से ऐसा नहीं करता है: यह मेरी छाप है ... मुझे लगता है क्योंकि यह बहुत अधिक होगा - प्रत्येक स्थान की जांच करने के लिए जहां यह अपडेट हो रहा है। यह स्विंग कोड को फहराएगा, कोड की समीक्षा और रखरखाव को अलग करेगा।

दूसरी तरफ यह जानने के लिए कि यह GUI थ्रेड के अंदर निष्पादित नहीं हो रहा है और invokeLater को कॉल करने के लिए यह भिन्न नहीं है। यह तब होगा जब स्वयं के आवेदन ने कुछ थ्रेड लॉन्च किया था।

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