2010-06-07 7 views
8

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

मुझे कहीं भी नहीं मिला कि क्या ईडीटी पर क्लासलोडिंग भी अनिवार्य है या क्या हम पृष्ठभूमि धागे में कुंजी स्विंग कक्षाओं को प्री-लोड कर सकते हैं? क्या इस पर सूर्य/ओरेकल से कोई आधिकारिक बयान है? क्या कोई कक्षाएं हैं जो गैर-थ्रेडसेफ स्थैतिक स्थिति को पकड़ने के लिए जानी जाती हैं, इसलिए ईडीटी पर लोड होने की आवश्यकता है?

नेमी के प्रश्न को संबोधित करने के लिए स्पष्टीकरण: यह एक व्यावहारिक मुद्दा है। हमारे एप्लिकेशन के स्टार्टअप समय का एक बड़ा हिस्सा, क्लासलोडिंग और ईडीटी पर फ़ॉन्ट/छवि-लोडिंग बिताया जाता है। इनमें से अधिकांश को स्विंग और संबंधित पुस्तकालयों के लिए जिम्मेदार ठहराया जा सकता है।

यहां कुछ पृष्ठभूमि है: कई अन्य स्विंग ऐप्स के रूप में, स्टार्टअप पर हम UI को अधिक उत्तरदायी बनाने के लिए कई रूपों का निर्माण कर रहे हैं। प्रोफाइलिंग के बाद, हमने पाया कि फॉर्म निर्माण के लिए वास्तविक समय अपेक्षाकृत तेज़ है - सभी कक्षाओं और फोंटों की धीमी गति क्या है (डिस्क पढ़ने धीमी ऑन-एक्सेस वायरस स्कैनर, निगरानी स्कैनर, ऑडिट ट्रैकर और भगवान के साथ कॉर्पोरेट सेटअप में है एचडीडी चालक पर और क्या लगाया गया)।

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

मैं क्या पूछ रहा हूं कि यह एक सुरक्षित अभ्यास है, एक अच्छा अभ्यास है या हैक?

+0

विशेष रूप से, दो सिंगलटन कक्षाएं मैं UIManager और AppContext थे के बारे में सोच सकते हैं। दोनों javadocs यह नहीं बताते हैं कि वे थ्रेडसेफ होना चाहिए। ऐपकॉन्टेक्स्ट ठीक से सिंक्रनाइज़ दिखता है, सिवाय इसके कि isDisposed() विधि राज्य को ठीक से नहीं पढ़ती है (सिंक्रनाइज़ेशन की आवश्यकता है)। UIManager सभी के लिए नि: शुल्क है, हालांकि एक बार ईडीटी शुरू होने के बाद, मुझे नहीं लगता कि कोई अन्य धागा इसे बदल देगा। – ddimitrov

+0

यह एक दिलचस्प सवाल है। क्या यह पूरी तरह अकादमिक है, या क्या कोई वास्तविक समस्या है जिसे आप हल करने की कोशिश कर रहे हैं? मैं एक अच्छा कारण नहीं सोच सकता कि आप ऐसा करना चाहते हैं। – Nemi

+0

@Nemi, प्रश्न – ddimitrov

उत्तर

2

सबूत यह सुझाव देते हैं कि यह सुरक्षित है - लेकिन फिर, जैसा कि डीडीमिट्रोव टिप्पणियों में कहता है - बाधाएं गैर-प्रकाशित परिवर्तनों के कारण सूक्ष्म धागे कीड़े नहीं ढूंढने के पक्ष में हैं क्योंकि विशिष्ट मशीनों में केवल कुछ कोर होते हैं, और एल 2/एल 3 कैश साझा किए जाते हैं। (एल 1 कैश प्रति कोर हैं, लेकिन औपचारिक रूप से बहुत छोटे हैं।)

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

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

+0

धन्यवाद, यह मेरे प्रश्न का उत्तर देता है। – ddimitrov

+0

इसके बारे में सोचकर, पुराने से बने एक नए नए ईडीटी पर स्विंग चलाना सुरक्षित है, क्योंकि Thread.start() एक सुरक्षित प्रकाशन है। फिर परिवर्तनों को देखने के लिए हमें या तो थ्रेड की आवश्यकता है।अस्थायी प्रेषक या स्पॉन में शामिल हों (अभी तक एक और प्रेषक (जो नए भारित वर्गों को देखेंगे) और पुराने ईडीटी को मार डालें। गन्दा लगता है ... – ddimitrov

+0

यदि आप स्पिन लाइब्रेरी का उपयोग करते हैं तो विवरणों का ध्यान रखा जाता है। मुझे नहीं लगता कि यह उतना ही गन्दा है जितना आप डरते हैं - माध्यमिक ईडीटी को एक ईवेंट पोस्ट करके समाप्त किया जा सकता है। आप यह सब करते हैं, और Thread.join() सभी कक्षाओं को लोड करने के बाद। – mdma

0

यद्यपि आप तकनीकी रूप से सही हैं - मैंने कभी भी एक अलग धागे में रूपों को प्रस्तुत करने में कोई समस्या नहीं सुना है जब तक कि आप ईडीटी को छोड़कर एहसास हो जाने के बाद उनके साथ कुछ भी नहीं करते हैं (सूर्य के अनुसार मूल दिशानिर्देश)।

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

आपके प्रश्न के अनुसार, मुझे यकीन है कि आप कक्षाओं को तब तक लोड कर सकते हैं जब तक आप किसी ऑब्जेक्ट को तुरंत चालू नहीं करते हैं और फिर भी सख्त दिशानिर्देशों के भीतर होते हैं।

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

+0

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

+0

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

+0

जब आप कक्षाओं को लोड करते हैं तो लोडिंग थ्रेड में चलने वाले किसी भी स्थिर प्रारंभकर्ता और किसी भी गैर-अंतिम स्थैतिक स्थिति सुरक्षित-प्रकाशन नियमों के अधीन होती है। मेरा मानना ​​है कि स्विंग में कोई ज्यादा परिवर्तनीय स्थैतिक राज्य नहीं है, लेकिन (जैसा कि मैंने उदाहरण दिए हैं) कुछ हैं। अन्यथा मैं मानता हूं कि किसी समस्या की संभावना कम है, लेकिन जब कोई समस्या हो तो निदान या यहां तक ​​कि पुन: उत्पन्न करने के लिए असंभव होगा। – ddimitrov

2

यह सुरक्षित है। देखें: http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html (एकल थ्रेड नियम)

आप डर रहे हैं या कुछ प्रतिक्रिया/डिबग चाहते हैं, इस FEST/घुमाओ उपकरण पर एक नजर है: http://fest.easytesting.org/swing/wiki/pmwiki.php?n=FEST-Swing.EDT ("परीक्षण है कि GUI घटक के लिए पहुँच EDT में किया जाता है") - यह एक कस्टम RepaintManager है जो ईडीटी एक्सेस पॉलिसी का उल्लंघन करते समय विफल रहता है।

आप इस उपयोगी रूप में अच्छी तरह मिल सकता है: http://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html

वे वर्ग लोड हो रहा है स्पष्ट रूप से उल्लेख नहीं है, लेकिन किसी की व्याख्या कैसे करते क्या EDT पहुँच नीति के बारे में है।

+0

फिर से मैं यहां ईडीटी नीति उल्लंघन के बारे में बात नहीं कर रहा हूं। ईडीटी नीति एक मनमाना नियम नहीं है, यह एक कारण के लिए है और मुझे लगता है कि यह पूरा नहीं हुआ है। अधिक जानकारी के लिए एमडीएमए का जवाब देखें। – ddimitrov

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