7

निर्माता-उपभोक्ता पैटर्न की मेरी समझ यह है कि इसे निर्माता और उपभोक्ता के बीच साझा की गई कतार का उपयोग करके कार्यान्वित किया जा सकता है। निर्माता एक साझा कतार में काम प्रस्तुत करता है, उपभोक्ता इसे पुनर्प्राप्त करता है और इसे संसाधित करता है। इसे निर्माता द्वारा सीधे उपभोक्ता को प्रस्तुत किया जा सकता है (उपभोक्ता की निष्पादक सेवा को सीधे प्रस्तुत करने वाले निर्माता धागे)।निर्माता उपभोक्ता - निष्पादक का उपयोग करना .newFixedThreadPool

अब, मैं एक्जिक्यूटर्स क्लास को देख रहा हूं जो थ्रेड पूल के कुछ सामान्य कार्यान्वयन प्रदान करता है। Spec के अनुसार, newFixedThreadPool विधि, "एक साझा असंबद्ध कतार को संचालित करने वाले थ्रेड की एक निश्चित संख्या का पुन: उपयोग करती है"। वे किस कतार के बारे में बात कर रहे हैं?

यदि निर्माता सीधे उपभोक्ता को कोई कार्य सबमिट करता है, तो क्या यह निष्पादक सेवा की आंतरिक कतार है जिसमें Runnables की सूची शामिल है?

या क्या यह मध्यवर्ती कतार है, यदि निर्माता एक साझा कतार में सबमिट करता है?

क्या मुझे पूरा बिंदु याद आ रहा है, लेकिन क्या कोई स्पष्टीकरण देगा?

उत्तर

4

आप सही हैं, ExecutorService न केवल एक धागा पूल है, बल्कि यह एक पूर्ण निर्माता-उपभोक्ता कार्यान्वयन है। यह आंतरिक कतार वास्तव में Runnable एस (FutureTask सटीक होने के लिए एक थ्रेड-सुरक्षित कतार है) submit() कार्य करता है।

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

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

+0

बस स्पष्ट करने के लिए: 'ExecutorService' सिर्फ एक इंटरफेस है। आप * एक ऐसे वर्ग के साथ * निष्पादक सेवा 'को कार्यान्वित कर सकते हैं जो एक ही थ्रेड में जितनी जल्दी हो सके, प्रत्येक रननेबल को चलाता है (और मेरा मानना ​​है कि' java.util.concurrent' पैकेज में कोई कार्यान्वयन है जो बस करता है) । लेकिन * अभ्यास में *, अधिकांश निष्पादक सेवा कार्यान्वयन एक पूर्ण निर्माता-उपभोक्ता कार्यान्वयन हैं। –

+0

आप बिल्कुल सही हैं, 'एक्जिक्यूटर्स सेवा' से मेरा मतलब है "* एक्जिक्यूटर्स.न्यूफिक्स्ड थ्रेडपूल() 'द्वारा लौटाई गई चीज़' जो 'एक्जिक्यूटर्स सर्विस' * लागू करती है। स्पष्टीकरण के लिए धन्यवाद। –

+1

धन्यवाद दोस्तों। इसलिए, यदि मैं newFixedThreadPool (8) का उपयोग कर निष्पादक सेवा बनाता हूं और उसके बाद 1000 रनने योग्य कार्यों को निष्पादित करता हूं, तो कृपया परिदृश्य की मेरी समझ की पुष्टि करें: 1. अधिकतम 8 धागे पर 2 प्रसंस्करण की शुरुआत में बनाया जाएगा , जबकि 8 धागे व्यस्त हैं, 992 कार्यों को आंतरिक कतार में आयोजित किया जाएगा 3. इसके अलावा, क्योंकि यह एक असंबद्ध कतार है, निष्पादक सेवा में सबमिट किए जा सकने वाले कार्यों की संख्या पर कोई ऊपरी सीमा नहीं है। उपरोक्त परिदृश्य में क्या प्रभाव होगा यदि मैं एक बाध्य कतार के साथ एक एक्जिक्यूटर्स सेवा बनाता हूं? क्या यह बेहतर प्रदर्शन करेगा? धन्यवाद, ओ – Oxford

0

इस की जाँच करें:
Producer-Consumer example in Java (RabbitMQ) (यह एक और पुस्तकालय के लिए लिखा है, लेकिन यह जावा में है और यह स्पष्ट रूप से अवधारणा को दर्शाता है;)
आशा है कि यह मदद करता है!

P.S.:Actually, यह कई उदाहरण है, लेकिन आप अंदाजा हो;)

1
public class Producer extends Thread { 
    static List<String> list = new ArrayList<String>(); 

    public static void main(String[] args) { 
     ScheduledExecutorService executor = Executors 
       .newScheduledThreadPool(12); 
     int initialDelay = 5; 
     int pollingFrequency = 5; 
     Producer producer = new Producer(); 
     @SuppressWarnings({ "rawtypes", "unused" }) 
     ScheduledFuture schedFutureProducer = executor.scheduleWithFixedDelay( 
       producer, initialDelay, pollingFrequency, TimeUnit.SECONDS); 
     for (int i = 0; i < 3; i++) { 
      Consumer consumer = new Consumer(); 
      @SuppressWarnings({ "rawtypes", "unused" }) 
      ScheduledFuture schedFutureConsumer = executor 
        .scheduleWithFixedDelay(consumer, initialDelay, 
          pollingFrequency, TimeUnit.SECONDS); 
     } 

    } 

    @Override 
    public void run() { 
     list.add("object added to list is " + System.currentTimeMillis()); 
           ///adding in list become slow also because of synchronized behavior 
    } 
} 

class Consumer extends Thread { 

    @Override 
    public void run() { 
     getObjectFromList(); 
    } 

    private void getObjectFromList() { 
     synchronized (Producer.list) { 
      if (Producer.list.size() > 0) { 
       System.out.println("Object name removed by " 
         + Thread.currentThread().getName() + "is " 
         + Producer.list.get(0)); 
       Producer.list.remove(Producer.list.get(0)); 
      } 
     } 
    } 
} 
संबंधित मुद्दे