2012-10-06 7 views
5

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

executor.submit(Runnable) 

चलें कहते हैं कि हम शुरू में कुछ सूत्र बना सकते हैं और जब काम आ हम उन्हें (धागा) के लिए कार्य आवंटित किसी भी कतार impl का उपयोग कर। लेकिन पूरा करने के बाद यह कार्य कैसे कर सकता है फिर से अपने पूल के लिए एक धागा वापसी जब अनुसार धागे के जीवन चक्र का कहना है कि

"अपनी दौड़ विधि के निष्पादन के बाद यह समाप्त राज्य में चला जाता है और फिर से इस्तेमाल किया जा सकता है"

मुझे समझ में नहीं आ रहा है कि थ्रेड पूल किसी भी कार्य को अपने कतार में निष्पादित करने के लिए लगातार थ्रेड के लिए कैसे काम करता है।

यह बहुत अच्छा होगा अगर कोई मुझे कार्य पूरा होने के बाद थ्रेड पुन: उपयोग का उदाहरण प्रदान कर सके।

!! अग्रिम धन्यवाद। !!

+0

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

उत्तर

2

"अपनी दौड़ विधि के निष्पादन के बाद यह समाप्त राज्य में चला जाता है और फिर से इस्तेमाल किया जा सकता है"

यह खत्म नहीं करता है अपने run() इसके बजाय यह (एक पाश जो रन चलाता है) आपके द्वारा प्रदान किए जाने वाले कार्यों में से।


थ्रेड पूल पैटर्न को नाटकीय रूप से सरल बनाना आपके पास ऐसा कोड है जो इस तरह दिखता है।

final BlockingQueue<Runnable> tasks = new LinkedBlockingQueue<Runnable>(); 

public void submit(Runnable runs) { 
    tasks.add(runs); 
} 

volatile boolean running = true; 

// running in each thread in the pool 
class RunsRunnable implement Runnable { 
    public void run() { 
     while(running) { 
      Runnable runs = tasks.take(); 
      try { 
       runs.run(); 
      } catch(Throwable t) { 
       // handles t 
      } 
     } 
    } 
} 

इस उदाहरण में, आप देख सकते हैं कि अपने आप में नहीं है जब तक पूल बंद है, जबकि (धागा के प्रत्येक कार्य को पूरा करता, रन() की) रन।

+0

लेकिन अगर हम सीधे रन विधि निष्पादित करते हैं तो कोई धागा स्पॉन नहीं होगा। यह केवल विधि को निष्पादित करेगा। तो क्या इसका मतलब यह है कि निष्पादित (अनुकूलित इम्प्लेक्स में) किसी भी कार्य को स्वीकार कर सकता है जिसमें समान अनुबंध होगा (जैसे रननेबल रन()) और हमें पूल थ्रेड में उस अनुबंध विधि को कॉल करना होगा। कार्य के रूप में चलाने योग्य या कॉल करने योग्य का कोई उपयोग नहीं? – Virendra

+0

मैंने एक उदाहरण जोड़ा है। मुझे लगता है कि आप मान रहे हैं कि जब Runtime.run() लौटाता है, तो कुछ खास होता है जब यह किसी अन्य की तरह एक विधि कॉल करता है। एक धागा बंद हो जाता है जब इसके लिए और कुछ नहीं होता है। बीटीडब्ल्यू UncaughtExceptionHandler को चलाने के बाद बुलाया जा सकता है() बाहर निकलता है इसलिए धागा तुरंत समाप्त नहीं होता है। –

0

अधिक जानकारी और कार्यान्वयन उदाहरण के लिए आप यहां एक नज़र डाल सकते हैं: http://www.ibm.com/developerworks/library/j-jtp0730/index.html। पूल में धागे इंतजार करेंगे यदि कतार खाली है और प्रत्येक को सूचित किया जाएगा कि कतार में कुछ तत्व हैं।

+0

यहां एक ही प्रश्न है। जब उनके अनुबंध विधि को कॉल करने के लिए उनका एकमात्र उपयोग होता है तो कार्य को चलाने योग्य या कॉल करने योग्य क्यों होना आवश्यक है। आर = (रननेबल) queue.removeFirst(); r.run(); क्या केवल रननेबल होना जरूरी है। हम किसी अन्य ऑब्जेक्ट को पोरवाइड कर सकते हैं जिसमें रन विधि है। चूंकि इसका आखिरकार लक्ष्य पूलिंग धागे का उपयोग करके बुलाया जाना चाहिए उससे ज्यादा नहीं? – Virendra

0

ExecutorService executor = Executors.newFixedThreadPool(2);

- ऊपर बयान 2.

executor.execute(new Worker());

की निश्चित आकार के साथ एक ThreadPool बनाया - ऊपर बयान वर्ग कार्यकर्ता जो Runnable लागू किया गया है का एक उदाहरण ले जाता है इंटरफेस।

- अब Executors कार्य को निष्पादित करने वाला एक मध्यवर्ती वस्तु है। जो थ्रेड ऑब्जेक्ट्स का प्रबंधन करता है।

- ऊपर बयान run() विधि क्रियान्वित द्वारा निष्पादित किया जाएगा, और एक बार रन() विधि पूरा करता है, धागा doesnot मृत स्थिति में जाने लेकिन पूल में वापस ले जाता है, एक और काम सौंपा है करने के लिए इंतजार कर इसके लिए, इसलिए यह एक बार फिर से चलने योग्य राज्य में जा सकता है और फिर दौड़ने के लिए, यह सब निष्पादकों द्वारा संभाला जाता है।

executor.shutdown();

- ऊपर बयान इच्छा बंद निष्पादकों ही है, शान से कि केन्द्रीय वस्तु है, जो बारी में पंजीकृत निष्पादकों के प्रत्येक बंद हो सकता है पर सभी धागे यह द्वारा प्रबंधित की बंद .. shutdown() से निपटने ।

////////// Edited Part////////////////////// 

- सभी Runnable सबसे पहले एक रन() विधि जो कुछ भी वापस नहीं कर सकते है, और रन() विधि नहीं, एक जाँच अपवाद फेंक कर सकते हैं तो प्रतिदेय जावा 5, पैरामीट्रिक प्रकार का है, जिसमें पेश किया गया था, और कॉल() नामक एक विधि है, और यह लौटने में सक्षम है, और चेक अपवाद फेंकने में सक्षम है।

अब इस उदाहरण देखें:

Thread t = new Thread(new Worker()); 

t.run(); 

t.start(); 

-t.run()run() विधि करने के लिए बस एक साधारण कॉल है, इस एक thread of execution अवधि नहीं होंगे।

-t.start() जबकि बातें thread of execution की initialization के लिए महत्वपूर्ण है, और फिर कॉलRunnable की run() विधि, और फिर आवंटित के लिए तैयार करताTaskनवthread of execution का गठन, और को जल्दी से लौटता है ....

Swing औरका उपयोग करते समय जावा में थ्रेड आवश्यक हो जाता है। मुख्य रूप से जीयूआई घटक

+0

@ विवेक क्या आप नीचे दिए गए प्रश्न में दिए गए प्रश्न का उत्तर दे सकते हैं। रननेबल या कॉल करने योग्य क्यों कार्य करें। क्या मैं कोई obj दे सकता हूं जिसमें इसमें चल रहा है() विधि। पूलिंग थ्रेड के रूप में केवल कॉल() से कोई थ्रेड नहीं बना रहा है। तो वास्तव में कोई रननेबल आवश्यक नहीं है? – Virendra

+0

@ वीरेंद्र कृपया मेरे संपादित उत्तर को देखें ..... –

+0

इसलिए निष्पादक मामले में, t.run() काम कर रहा है क्योंकि हम कार्य निष्पादित करते समय कोई t.start() कॉल नहीं बना रहे हैं। तो यह किसी भी कार्य को प्रदान करने जैसा ही है जो रननेबल के कार्यान्वयन नहीं हो सकता है लेकिन इसमें रन() विधि है। निष्पादक के पूलवर्कर केवल रन विधि को निष्पादित करते हैं (जैसे t.run()) कार्य में थ्रेड गुणों का कोई उपयोग नहीं करते? – Virendra

0

मैं पूरी तरह से पीटर से सहमत हूं लेकिन स्पष्ट समझ के लिए निष्पादक सेवा निष्पादन प्रवाह से संबंधित कदम जोड़ना चाहता हूं।

  • आप धागे की पूल (निश्चित आकार पूल) बनाते हैं, तो इसका मतलब है कि यह नहीं है कि धागे बनाए गए थे।
  • आप सबमिट करें और/या नए कार्य (Runnuble या Callable) पर अमल नया थ्रेड juts बनाया जाएगा यदि बनाया धागे पूल के < आकार पूल की ओर लौटने
  • निर्मित धागे नहीं की गिनती, धागे को रोकने में नया मान के लिए प्रतीक्षा कर सकते हैं कतार, इस बिंदु पर हम पुल
  • पूल निष्पादन के सभी धागे ऊपर वर्णित पीटर जैसे सभी धागे को कॉल कर सकते हैं।
1

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

नीचे उदाहरण पूल में .removeFromQueue() इसे क्रमशः चलाएगा।

public class MyThread<V> extends Thread { 
    private MyThreadPool<V> pool; 
    private boolean active = true; 

    public boolean isActive() { 
     return active; 
    } 

    public void setPool(MyThreadPool<V> p) { 
     pool = p; 
    } 

    /** 
    * Checks if there are any unfinished tasks left. if there are , then runs 
    * the task and call back with output on resultListner Waits if there are no 
    * tasks available to run If shutDown is called on MyThreadPool, all waiting 
    * threads will exit and all running threads will exit after finishing the 
    * task 
    */ 
    @Override 
    public void run() { 
     ResultListener<V> result = pool.getResultListener(); 
     Callable<V> task; 
     while (true) { 
      task = pool.removeFromQueue(); 
      if (task != null) { 
       try { 
        V output = task.call(); 
        result.finish(output); 
       } catch (Exception e) { 
        result.error(e); 
       } 
      } else { 
       if (!isActive()) 
        break; 
       else { 
        synchronized (pool.getWaitLock()) { 
         try { 
          pool.getWaitLock().wait(); 
         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 
       } 
      } 
     } 
    } 

    void shutdown() { 
     active = false; 
    } 

आवश्यकता अपने थ्रेड पूल डिजाइन करने के लिए

public MyThreadPool(int size, ResultListener<V> myResultListener) { 
     tasks = new LinkedList<Callable<V>>(); 
     threads = new LinkedList<MyThread<V>>(); 
     shutDown = false; 
     resultListener = myResultListener; 
     for (int i = 0; i < size; i++) { 
      MyThread<V> myThread = new MyThread<V>(); 
      myThread.setPool(this); 
      threads.add(myThread); 
      myThread.start(); 
     } 
    } 
संबंधित मुद्दे