2013-06-25 5 views
8

जब कोई जावा प्रोग्राम System.out.println() या स्कैला प्रोग्राम कॉल करता है तो println() थ्रेड ब्लॉक करता है?क्या कंसोल आउटपुट अवरुद्ध करने वाला ऑपरेशन है?

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

और यदि यह एक अवरुद्ध ऑपरेशन है: प्रदर्शन को अनुकूलित करने के लिए मैं क्या कर सकता हूं?

  • क्या मुझे कंसोल आउटपुट के लिए समर्पित थ्रेड का उपयोग करना चाहिए, ताकि थ्रेड केवल एक ही ब्लॉक हो?
  • कोई अन्य सलाह?

बेशक मैं आउटपुट की मात्रा को कम करने या स्ट्रिंगबिल्डर में कुछ आउटपुट एकत्र करने का प्रयास कर सकता हूं और बैच में इसे एक साथ प्रिंट कर सकता हूं, जो आउटपुट ऑपरेशंस की संख्या को कम करता है।

उत्तर

12

जब कोई जावा प्रोग्राम System.out.println() या स्कैला प्रोग्राम कॉल करता है तो println() थ्रेड ब्लॉक करता है?

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

क्या मुझे कंसोल आउटपुट के लिए समर्पित थ्रेड का उपयोग करना चाहिए, ताकि थ्रेड केवल एक ही ब्लॉक हो?

उत्कृष्ट विचार, हाँ। फिर यह धागा एक BufferedWriter या कुछ प्रकार के log4j या अन्य लॉगिंग पैकेज के माध्यम से लिख सकता है जो System.out की तुलना में बहुत अधिक प्रदर्शनकारी होगा। सिंक्रोनस वाले संदेशों को कतारबद्ध करने के लिए आपको BlockingQueue जैसे कुछ उपयोग करने की आवश्यकता होगी, लेकिन IO इस कतार को कभी भी अवरुद्ध नहीं करेगा जब तक कि आप आईओ चैनल की तुलना में संदेशों को तेज़ी से तैयार नहीं कर सकते हैं।

बेशक मैं आउटपुट की मात्रा को कम करने या स्ट्रिंगबिल्डर में कुछ आउटपुट एकत्र करने का प्रयास कर सकता हूं और बैच में इसे एक साथ प्रिंट कर सकता हूं, जो आउटपुट ऑपरेशंस की संख्या को कम करता है।

BufferedWriter आपके लिए इसका ख्याल रखेगा।

कोई अन्य सलाह?

  • के रूप में उल्लेख किया है, एक बेहतर लॉगिंग पैकेज या एक एकल पिरोया लेखक का उपयोग करें।
  • एक अलग भौतिक डिस्क पर लॉग लिखें जिसमें अधिक आईओ बैंडविड्थ है।
  • अपनी आईओ बैंडविड्थ बढ़ाने के लिए मेमोरी फ़ाइल-सिस्टम या हार्डवेयर पर स्विच करें। एसएसडी ++।
  • इसे वास्तविक अवरुद्ध बंद बॉक्स करने के लिए नेटवर्क के माध्यम से किसी अन्य बॉक्स में भेजें।
  • फ्लाई पर इसे संपीड़ित करने के लिए GzipOutputStream का उपयोग करें।
+0

* एक अलग फ़ाइल सिस्टम में लॉग लिखें। * आपका मतलब अलग है भौतिक ड्राइव? या यदि आपका मतलब है कि एक फ़ाइल सिस्टम को ऐसे कार्यों के लिए बेहतर अनुकूलित किया गया है (जैसे ext * बनाम btrfs), तो क्या आप नाम प्रकट कर सकते हैं? –

+0

नहीं, मेरा मतलब वास्तव में आईओ श्रृंखला है, अलग-अलग एफएस प्रकार @ ओम-नाम-नाम नहीं। महान उपयोगकर्ता नाम बीटीडब्ल्यू। :-) – Gray

+0

यह। यह एक अच्छी तरह से स्वरूपित और सहायक उत्तर है। – Andy

4

यह पर निर्भर करता है। विंडोज ओएस यह एक अवरुद्ध ऑपरेशन है और कंसोल में कुछ प्रिंट करने के लिए बहुत सारे कर्नेल सामान शामिल हैं। यूनिक्स-ओएस की तरह ऑपरेशन buffered है इसलिए इसे धीमा नहीं माना जाता है।

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

+0

यह भी याद रखें कि System.out कंसोल पर जरूरी नहीं है (इसे "कमांड> out.txt" के साथ फ़ाइल में रीडायरेक्ट किया गया हो सकता है) – faffaffaff

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