2012-04-14 22 views
6

मेरी प्रोजेक्ट में मैं एक जावा निष्पादन ढांचा तैयार कर रहा हूं जो क्लाइंट से कार्य अनुरोध प्राप्त करता है। कार्य (अलग-अलग आकार) कार्यों के एक सेट में टूटा हुआ है और फिर प्रसंस्करण के लिए कतारबद्ध है। प्रत्येक प्रकार के कार्य को संसाधित करने के लिए अलग-अलग कतार हैं और प्रत्येक कतार थ्रेडपूल से जुड़ी है। थ्रेडपूल इस तरह से कॉन्फ़िगर किए गए हैं कि इंजन का समग्र प्रदर्शन इष्टतम है।कार्य/कार्य चोरी ThreadPoolExecutor

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

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

फोर्क/जॉइन के बारे में पढ़ें लेकिन यह मेरी आवश्यकताओं के लिए उपयुक्त नहीं लगता है। इस समाधान को बनाने के लिए कोई सुझाव या वैकल्पिक तरीका बहुत उपयोगी हो सकता है।

धन्यवाद एंडी

+1

आपको अपने सभी CPUs को व्यस्त रखने के बारे में सोचना चाहिए। इससे कोई फर्क नहीं पड़ता कि अगर आप अपने सीपीयू का सबसे अच्छा उपयोग कर रहे हैं तो आपके कुछ धागे निष्क्रिय हैं। –

+0

यदि आपके थ्रेड पूल में आपके पास सीपीयू के रूप में कई धागे हैं, तो कोई भी व्यक्तिगत थ्रेड पूल सभी सीपीयू को "चोरी" कर सकता है भले ही अन्य सभी थ्रेड पूल निष्क्रिय हों। –

+0

@ पीटर Lawrey - यह सच है, लेकिन यदि बहुत सारे पूल हैं, तो आपके पास खराब प्रदर्शन हो सकता है यदि सभी पूल में सभी धागे एक ही समय में काम कर रहे हों। – jtahlborn

उत्तर

1

आप एक कस्टम BlockingQueue कार्यान्वयन (मुझे लगता है कि आप मुख्य रूप से offer() और take() तरीकों को लागू करने की जरूरत है) जो एक "प्राथमिक" कतार और 0 या अधिक माध्यमिक कतारों के द्वारा समर्थित है को लागू कर सकते हैं। गैर-खाली होने पर हमेशा प्राथमिक बैकिंग कतार से लिया जाएगा, अन्यथा यह द्वितीयक कतारों से खींच सकता है।

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

+0

यह एक अच्छा विचार है जो मैं पीओसी के साथ प्रयास करने के लिए झुका रहा हूं। –

2

क्या आपने ForkJoinPool पर विचार किया है? फोर्क-जॉइन फ्रेमवर्क को एक अच्छा मॉड्यूलर फैशन में कार्यान्वित किया गया था ताकि आप केवल काम-चोरी थ्रेड पूल का उपयोग कर सकें।

+1

एपीआई पढ़ें लेकिन अभी भी यह पता नहीं लगा सकता कि यह नियमित ThreadPoolExecutor से अलग कैसे है। शायद वहां कुछ बेहतर पहलू गायब हैं। –

+0

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

2

जावा 8 में Executors कक्षा में इसके लिए कारखाने और उपयोगिता विधियां हैं। एक कार्य-चोरी थ्रेड पूल (here) का कार्यान्वयन है, जो मुझे विश्वास है, वही है जो आप चाहते हैं।

+0

केवल इस नुकसान के साथ मैं यह देखता हूं कि यह वैश्विक फोर्ड से इन धागे को उधार लेने की बजाय मांग पर नया फोर्कजॉइन थ्रेड बनाता है - एक सामान्य पूल या पूल हो सकता है जो ग्राहक पास कर सकता है। –

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