2015-04-07 17 views
9

मैं वसंत मल्टीथ्रेडिंग में प्रवेश करने की कोशिश कर रहा हूं और मेरे कुछ प्रश्न हैं।वसंत में मल्टीथ्रेडिंग

मेरे पास थ्रेडरेटिंग क्लास में चलने योग्य विधि है। अब मैं इसका उपयोग करने का सबसे अच्छा तरीका नहीं जानता हूं।

विकल्प 1 मैंने पाया:

private void updateRating() { 
     ExecutorService executor = Executors.newFixedThreadPool(10); 

    for (int i = 0; i < 10; i++) { // test 
     // thread part 
     Runnable worker = new ThreadRating(path, i, products.get(i), dao, fileHandler); 
     executor.execute(worker); 
    } 
    executor.shutdown(); 
    try { 
     executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); 
    } catch (InterruptedException e) { 
     log.error("There was an error when ending threads"); 
     System.exit(1); 
    } 
    System.out.println("Finished all threads"); 
} 

यह ठीक चल रहा हो लगते हैं। लूप के बाद, यह तब तक इंतजार करता है जब तक धागे खत्म नहीं हो जाते हैं और समाप्त होते हैं।

दूसरा विकल्प मैं

private TaskExecutor taskExecutor; 

public UpdateBO(TaskExecutor taskExecutor) { 
    this.taskExecutor = taskExecutor; 
} 

private void updateRating() { 
     for (int i = 0; i < 10; i++) { // test 
      Runnable worker = new ThreadRating(path, i, products.get(i), dao, fileHandler); 
      taskExecutor.execute(worker); 
     } 
    // wait for threads to be finished before you go any further ?? 
     } 

की कोशिश की और xml फ़ाइल में मैं

<beans:bean id="taskExecutor" 
    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> 
    <beans:property name="corePoolSize" value="5" /> 
    <beans:property name="maxPoolSize" value="10" /> 
    <beans:property name="queueCapacity" value="25" /> 
    <beans:property name="waitForTasksToCompleteOnShutdown" value="true" /> 
</beans:bean> 

<beans:bean id="updateBO" class="UpdateBO"> 
    <beans:constructor-arg ref="taskExecutor" /> 
</beans:bean> 

यहाँ और मेरे सवाल कर रहे हैं:

  1. कि इन दो विकल्पों के बीच कोई अंतर है ? गति, स्मृति, संभव लीक? या वे वही हैं जो अलग-अलग लिखे गए हैं?
  2. क्या मुझे webservice का उपयोग करते समय पूल को बंद करने की आवश्यकता है? मुझे पता है कि दूसरे विकल्प में मुझे नहीं करना है, लेकिन यह webservice का उपयोग करते समय भी वही है?
  3. दूसरे विकल्प का उपयोग करते समय - मुझे तब तक इंतजार करना चाहिए जब तक कि सभी नौकरियां समाप्त नहीं हो जातीं? पहले विकल्प में मैंने पूल को बंद कर दिया और खत्म होने की प्रतीक्षा की। लेकिन दूसरे विकल्प में कार्य पूरा होने से पहले कोड अनुरोध समाप्त हो गया है।
  4. executor.execute(worker); - बस स्पष्ट करने के लिए। यह वास्तव में एक नया धागा नहीं बना रहा है, लेकिन यह एक कतार में कार्य जोड़ता है और यदि कतार पूर्ण हो जाती है तो यह कोड में इस लाइन पर सही जगह तक पहुंचने तक प्रतीक्षा करता है?

मुझे समझने में मदद के लिए धन्यवाद।

+0

पूल निष्पादकों को बंद करना अच्छा विकल्प नहीं है, कुछ वातावरण जैसे कि सक्षम सर्वर विकल्प के साथ ऐप सर्वर निष्पादक बंद करने का प्रयास सुरक्षा अपवाद का कारण बनता है। यदि आपको श्रमिकों को समाप्त होने तक प्रतीक्षा करने की आवश्यकता है, तो 'रननेबल' के बजाय 'भविष्य' का उपयोग करें। –

उत्तर

6
  1. मुख्य अंतर: विकल्प 1 में) आप हर updateRating() फोन पर नए प्रबंधक बनाने के लिए, विकल्प में 2) निष्पादक एक बार तैनाती समय पर बनाई गई है, तो आप नए रोजगार के साथ एक ही एकल निष्पादक खाते हैं। दूसरा दृष्टिकोण बहुत बेहतर है।

  2. आपको निष्पादक को बंद करने की आवश्यकता क्यों है? नए निष्पादक बनाना और कार्य को संसाधित होने तक प्रतीक्षा करने के लिए उन्हें बंद करना एंटीपाटरर्न है। याद रखें, निष्पादक सिस्टम संसाधनों को नियंत्रित करने के लिए बनाए गए हैं और इस तरह का इलाज किया जाना चाहिए। (ई जी। आपके पास 50 कनेक्शन के डीबी कनेक्शन पूल हैं - इसलिए डीबी एक्सेस की सेवा करने के लिए आप 50 थ्रेड के निष्पादक को बनाते हैं - कनेक्शन सीमा से अधिक होने के लिए। या आपके पास सर्वर पर 24 कोर हैं और सर्वोत्तम संभव तरीके से काम को समानांतर करने की आवश्यकता है) ।

    और जैसा कि मैंने टिप्पणी में उल्लेख किया है, कुछ वातावरण (जैसे ऐप सर्वर) में आपके पास अक्सर निष्पादक को बंद करने का कोई अधिकार नहीं है। इस तरह के प्रयास SecurityException का उत्पादन करेंगे।

  3. आप जब तक मजदूरों को अपनी नौकरी खत्म प्रतीक्षा करने के लिए की जरूरत है, मुख्य थ्रेड कॉल इसी future.get() से Callable बजाय Runnable साथ हर काम लपेट, तो - और जब तक काम खत्म यह रोकेंगे। टाइमआउट समर्थित हैं।Example

  4. बिल्कुल सही। थ्रेड को निष्पादक द्वारा ही बनाया और नष्ट कर दिया जाता है, जब ऐसा लगता है कि यह सबसे अच्छा समय है। यह देखने के लिए jvisualvm के साथ अपने ऐप की निगरानी करने का प्रयास करें।

+0

आपके उत्तर के लिए धन्यवाद। पूल के बारे में एक और सवाल - जहां तक ​​मैं समझता हूं, वसंत मेरे लिए हैडल करता है। तो अगर मैं कई वर्गों में धागे का उपयोग करना चाहता हूं, तो मैं बस बीन्स कॉन्फ़िगरेशन को <बीन्स: बीन आईडी = "अपडेटबीओ" वर्ग = "अपडेटबीओ, ..... और कक्षाएं आने के लिए बदलता हूं?"> और यह सभी के लिए संभाल लेगा कक्षाएं एक बार में? -> मैं इसे एक ही समय में कई कक्षाओं से कॉल कर सकता हूं, यह गुणा हो जाएगा या मुझे एक ही पूल मिल जाएगा? –

+0

बिल्कुल नहीं। एक बीन - एक वर्ग। इस निष्पादक की आवश्यकता वाले अन्य वर्गों के लिए, आपको इस विशेष निष्पादक बीन को कन्स्ट्रक्टर तर्क के रूप में पारित करने के लिए, एक और सेम को परिभाषित करने की आवश्यकता है। –

3

1.) विकल्प 1 बुरी तरह कार्यान्वित किया गया है क्योंकि आप स्थानीय रूप से अपनी निष्पादक सेवा को परिभाषित करते हैं और प्रत्येक उपयोग के बाद इसे बंद करते हैं। यह थ्रेड पूल बनाने के उद्देश्य को हरा देता है - इसे वैश्विक वस्तु होने की आवश्यकता है, इसलिए विकल्प 2 जाने का तरीका है।

2.) वेब सेवा को कॉल करते समय आपको निष्पादक सेवा को बंद करने की आवश्यकता नहीं है। यदि webservice कॉल का जवाब नहीं देता है तो आखिरकार समय समाप्त हो जाएगा और धागा पूर्ण निष्पादन भर जाएगा। अगर आप निष्पादक सेवा बंद कर देते हैं, तो यह अगली कॉल के लिए उपलब्ध नहीं होगा।

3.) यदि आपके धागे को समाप्त होने के बाद आपको कुछ प्रकार के नोटिफिकेशन की आवश्यकता है, तो आपको इसके बजाय के साथ Callable का उपयोग करना चाहिए।

4.) आपके निष्पादक सेवा में अधिकतम 10 धागे आवंटित किए गए हैं, यह उनसे अधिक नहीं होगा। यदि वे सभी व्यस्त हैं, तो आप तब तक निष्क्रिय रहेंगे जब तक कि उनमें से कोई भी थ्रेड उपलब्ध न हो जाए।

+0

बहुत बहुत धन्यवाद, यह अब बहुत स्पष्ट है। –

+0

और वास्तव में मुझे किसी अधिसूचना की आवश्यकता नहीं है, बस उन्हें समाप्त करने का इंतजार करें। ऐसा लगता है कि फ्यूचर्स रननेबल के लिए भी ऐसा करते हैं। –

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