2010-05-28 9 views
11

मेरे पास एक जावा एप्लिकेशन है जो सूर्य 1.6 32-बिट वीएम/सोलारिस 10 (x86)/नाहेलेम 8-कोर (कोर प्रति 2 धागे) पर चल रहा है।जावा थ्रेड संदर्भ को कम करने के लिए ओवरहेड

एप्लिकेशन में एक विशिष्ट उपयोगकेस कुछ बाहरी संदेश का जवाब देना है। मेरे प्रदर्शन परीक्षण वातावरण में, जब मैं बाहरी इनपुट प्राप्त करने वाले उसी थ्रेड में प्रतिक्रिया तैयार करता हूं और भेजता हूं, तो मुझे प्रतिक्रिया भेजने के लिए संदेश को अलग थ्रेड पर सौंपने से लगभग 50 हमें लाभ मिलता है। मैं हैंडऑफ करने के लिए SynchronousQueue के साथ ThreadPoolExecutor का उपयोग करता हूं।

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

उत्तर

0

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

  • सिंक्रनाइज़ कंटेनर (सरणी, सूचियां, मानचित्र ...) का उपयोग न करें। कंटेनर-प्रति-थ्रेड के बारे में सोचें।
  • हमने धागे के राउंड-रॉबिन पूल का उपयोग किया है। इस पूल में प्री-आवंटित धागे शामिल हैं और (!) किसी भी कतार के बिना ईवेंट के लिए बिल्कुल एक सुनते हैं। जब घटना बढ़ी, राउंड-रॉबिन से थ्रेड हटा दिया गया और दूसरा एक श्रोता बन गया। जब संभालना पूरा हो जाता है तो थ्रेड पूल में लौटाया जाता है।
+0

मुझे नहीं लगता कि प्रत्येक आने वाली घटना के लिए एक नया धागा बनाना सबसे अच्छा तरीका है। मेरे पास एक निश्चित थ्रेडपूल (शायद स्केलिंग भी) होगा जो आने वाली घटनाओं को एक या अधिक श्रोता धागे – RecursiveExceptionException

+0

"द्वारा सूचीबद्ध सूची में संसाधित करता है ..." प्रत्येक आने वाली घटना के लिए एक नया धागा सबसे अच्छा तरीका है "- जहां किया गया आप इसे मेरे पोस्ट में देखते हैं, जबकि मैंने लिखा: "... धागे के राउंड रॉबिन पूल"? – Dewfy

+0

ओह। मैंने इसे गलत समझा। केवल "थ्रेड हटाएं" देखा और सोचा: "हाँ यह अच्छा नहीं है": पी – RecursiveExceptionException

11

"स्वीकार्य देरी" पूरी तरह से आपके आवेदन पर निर्भर करता है। एक ही धागे पर सबकुछ से निपटने से वास्तव में मदद मिल सकती है यदि आपको बहुत सख्त विलंबता आवश्यकताएं मिलती हैं। सौभाग्य से ज्यादातर अनुप्रयोगों में कठोर आवश्यकताओं की आवश्यकता नहीं है।

बेशक, यदि केवल एक धागा अनुरोध प्राप्त करने में सक्षम है, तो प्रतिक्रिया की गणना के लिए उस धागे को बांधना मतलब होगा कि आप किसी अन्य अनुरोध को स्वीकार नहीं कर सकते हैं। आप जो कर रहे हैं उसके आधार पर आप "थ्रेड प्रति अनुरोध" मॉडल से बचने के लिए एसिंक्रोनस आईओ (आदि) का उपयोग कर सकते हैं, लेकिन यह काफी कठिन आईएमओ है, और अभी भी थ्रेड संदर्भ स्विचिंग के साथ समाप्त होता है।

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

नीचे की रेखा यह है कि विलंबता आवश्यकताओं को कठिन हो सकता है - मेरे अनुभव में वे थ्रूपुट आवश्यकताओं की तुलना में काफी कठिन हैं, क्योंकि वे स्केल करने के लिए बहुत कठिन हैं। यह वास्तव में हालांकि संदर्भ पर निर्भर करता है।

+0

धन्यवाद! मेरा मतलब था, "स्वीकार्य" के बजाय "अपेक्षित"। मैं एक विचार प्राप्त करना चाहता था अगर 50 हम बहुत बड़े हैं या इसे नीचे लाया जा सकता है। हां, मैं अगले संदेश को लेने में सक्षम होने के लिए प्राप्त थ्रेड ASAP को मुक्त करना चाहता हूं। इसके अलावा, मेरा अनुरोध प्रसंस्करण सीपीयू बाध्य है। –

1

क्या कोई कारण है कि आप LinkedBlockingQueue का उपयोग नहीं करते हैं, इसलिए आपका निर्माता SynchronousQueue के बजाय कुछ आइटम कतारबद्ध कर सकता है? कम से कम 1 आइटम के साथ एक कतार है ताकि आप बेहतर समांतरता प्राप्त कर सकें।

"प्रतिक्रिया" बनाम "तैयार" प्रक्रिया की गति क्या है? यदि आप बहुत महंगा हैं तो क्या प्रतिक्रियाओं को संभालने वाले एकाधिक धागे रखने के लिए आप थ्रेड पूल का उपयोग कर सकते हैं?

2

50us एक हैंडऑफ के लिए कुछ हद तक ऊंचा लगता है, आईएमई (सोलारिस 10/ऑप्टरन) एलबीक्यू आमतौर पर 30-35us रेंज में होता है जबकि एलटीक्यू (LinkedTransferQueue) उस से लगभग 5 गुना तेज होता है। जैसा कि अन्य उत्तरों में बताया गया है SynchronousQueue थोड़ा धीमा हो सकता है क्योंकि प्रस्ताव अन्य धागे तक नहीं लौटाता है।

मेरे परिणामों के मुताबिक सोलारिस 10 इस पर लिनक्स की तुलना में काफी धीमी है जो < 10us देखता है।

यह वास्तव में पीक लोड के तहत

  • आप कैसे प्रति सेकंड कई अनुरोध सेवा कर रहे हैं, कुछ बातों पर निर्भर करता?
  • आमतौर पर अनुरोध को संसाधित करने में कितना समय लगता है?

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

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