कोर पूल आकार बनाम थ्रेडपूल एक्ज़ीक्यूटर में अधिकतम पूल आकार


105

जब हम बात करते हैं तो कोर पूल आकार और अधिकतम पूल आकार के बीच अंतर क्या है ThreadPoolExecutor?
क्या इसे एक उदाहरण की मदद से समझाया जा सकता है?



जवाबों:


131

से इस ब्लॉग पोस्ट :

इसका उदाहरण लीजिए। थ्रेड पूल का आकार 1 है, कोर पूल का आकार 5 है, अधिकतम पूल का आकार 10 है और कतार 100 है।

जैसे ही अनुरोध आते हैं, धागे 5 तक बनाए जाएंगे और फिर 100 तक पहुंचने तक कार्यों को कतार में जोड़ दिया जाएगा। जब कतार पूरी हो जाएगी तो नए धागे बनाए जाएंगे maxPoolSize। एक बार जब सभी थ्रेड्स उपयोग में हो जाते हैं और कतार पूर्ण होती है तो कार्य अस्वीकार कर दिया जाएगा। जैसे-जैसे कतार कम होती जाती है, वैसे-वैसे सक्रिय धागों की संख्या बढ़ती जाती है।


क्या ये सही है? मैंने सोचा कि जब तक यह अधिकतम आकार तक नहीं पहुंचता तब तक नए धागे बनाए जाएंगे। फिर किसी भी नए धागे को कतार में रखा जाएगा। कृपया मुझे सही करें अगर मैं गलत हूं ..
ग्लाइड

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

3
एक दिलचस्प विधि है allowCoreThreadTimeOut(boolean)जो निष्क्रिय समय के बाद कोर धागे को मारने की अनुमति देती है। इसे सही पर सेट करना और सेट करना core threads= max threadsथ्रेड पूल को 0 और के बीच स्केल करने की अनुमति देता है max threads
जारोस्लाव पावलक

4
आपने अभी इसे यहाँ से कॉपी किया है bigsoft.co.uk/blog/index.php/2009/11/27/…
कुमार मनीष

1
अस्वीकृत कार्यों का क्या होता है?
वैक्स

54

यदि थ्रेड चल रहे हैं> corePoolSize & <maxPoolSize , तो कुल कार्य कतार पूर्ण होने और नया आने पर एक नया थ्रेड बनाएँ।

फार्म दस्तावेज़: (एक से अधिक कर रहे हैं corePoolSize लेकिन कम से कम maximumPoolSize धागे चल रहा है, एक नया धागा बनाया जाएगा केवल अगर कतार भर गई है।)

अब, एक सरल उदाहरण लें,

ThreadPoolExecutor executorPool = new ThreadPoolExecutor(5, 10, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(50));

यहाँ, 5 कोरपूलसाइज़ है - इसका अर्थ है कि जेवीएम पहले 5 कार्यों के लिए नए कार्य के लिए नया धागा बनाएगा। और अन्य कार्यों को कतार में तब तक जोड़ा जाएगा जब तक कि कतार पूर्ण नहीं हो रही है (50 कार्य)।

10 मैक्सपूलसाइज है - जेवीएम अधिकतम 10 धागे बना सकता है। मतलब अगर पहले से ही 5 टास्क / थ्रेड चल रहे हैं और कतार 50 लंबित कार्यों से भरी हुई है और यदि एक और नया अनुरोध / कार्य कतार में आ रहा है तो JVM 10 तक नए थ्रेड बनाएगा (कुल थ्रेड = पिछले 5 + नए 5) ;

new ArrayBlockingQueue (50) = कुल कतार आकार है - इसमें 50 कार्यों को कतारबद्ध किया जा सकता है।

एक बार सभी 10 सूत्र चल रहे हैं और यदि नया कार्य आ रहा है तो उस नए कार्य को अस्वीकार कर दिया जाएगा।

SUN द्वारा आंतरिक रूप से थ्रेड बनाने के नियम:

  1. यदि थ्रेड की संख्या कोरपूलसाइज से कम है, तो नया कार्य चलाने के लिए एक नया थ्रेड बनाएं।

  2. यदि कोर की संख्या के बराबर थ्रेड्स की संख्या बराबर (या इससे अधिक) है, तो कार्य को कतार में रखें।

  3. यदि कतार पूर्ण है, और थ्रेड्स की संख्या मैक्सपूलसाइज़ से कम है, तो कार्यों को चलाने के लिए एक नया थ्रेड बनाएँ।

  4. यदि कतार भरी हुई है, और थ्रेड की संख्या मैक्सपूलसाइज़ से अधिक या बराबर है, तो कार्य को अस्वीकार कर दें।

आशा है, यह हेल्पफुल है .. और कृपया मुझे सही करें अगर मैं गलत हूँ ...


21

से दस्तावेज़ :

जब कोई नया कार्य विधि निष्पादित (java.lang.Runnable) में प्रस्तुत किया जाता है, और कोरपूलसाइज थ्रेड्स से कम चल रहे हैं, तो अनुरोध को संभालने के लिए एक नया थ्रेड बनाया जाता है, भले ही अन्य वर्कर थ्रेड निष्क्रिय हों। अगर कोरपूलसाइज से ज्यादा हैं, लेकिन चलने वाले मैक्सिमम पॉलीसलाइज थ्रेड्स से कम हैं, तो एक नया धागा तभी बनाया जाएगा जब कतार पूरी भर जाएगी।

इसके अलावा:

CorePoolSize और maxPoolSize को एक ही सेट करके, आप एक निश्चित आकार का थ्रेड पूल बनाते हैं। एक अनिवार्य रूप से अनबाउंड मान जैसे कि Integer.MAX_VALUE, अधिकतम सेटिंग सेट करके, आप पूल को समवर्ती कार्यों की एक मनमानी संख्या को समायोजित करने की अनुमति देते हैं। ज्यादातर आम तौर पर, कोर और अधिकतम पूल आकार केवल निर्माण पर निर्धारित होते हैं, लेकिन उन्हें गतिशील रूप से सेटकोरपूलसाइज़ (इंट) और सेटमैक्सीमपूलसाइज़ (इंट) का उपयोग करके भी बदला जा सकता है।


1) जब विधि निष्पादित (java.lang.Runnable) में एक नया कार्य प्रस्तुत किया जाता है, और कोरपूलसाइज थ्रेड्स से कम चल रहे हैं, तो अनुरोध को संभालने के लिए एक नया थ्रेड बनाया जाता है, भले ही अन्य वर्कर थ्रेड निष्क्रिय हों। यदि निष्क्रिय थ्रेड हैं, तो अनुरोध को संभालने के लिए नया थ्रेड बनाने की आवश्यकता क्यों है?
user2568266

1
2) अगर कोरपूलसाइज से ज्यादा हैं, लेकिन चलने वाले अधिकतमपूलिसाइज थ्रेड्स से कम हैं, तो एक नया धागा केवल तभी बनाया जाएगा जब कतार भरी हो। मैं यहाँ CorePoolSize और maxPoolSize के बीच के अंतर को नहीं समझता। दूसरी बात, जब थ्रेड अधिकतम से कम हो तो एक कतार कैसे भरी जा सकती है? कतारें केवल तभी भरी जा सकती हैं जब थ्रेड्स अधिकतमपुलिसाइज के बराबर हों। है ना?
user2568266

9

यदि आप फ़ैक्टरी वर्ग ThreadPoolExecutorका उपयोग करने के बजाय मैन्युअल रूप से बनाने का निर्णय लेते हैं Executors, तो आपको इसके किसी एक निर्माता का उपयोग करके बनाना और कॉन्फ़िगर करना होगा। इस वर्ग का सबसे व्यापक निर्माण है:

public ThreadPoolExecutor(
    int corePoolSize,
    int maxPoolSize,
    long keepAlive,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    RejectedExecutionHandler handler
);

जैसा कि आप देख सकते हैं, आप कॉन्फ़िगर कर सकते हैं:

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

पंक्तिबद्ध कार्य की संख्या सीमित करना

समवर्ती कार्यों की संख्या को निष्पादित करना, आपके थ्रेड पूल को आकार देना, आपके एप्लिकेशन के लिए एक बड़ा लाभ और भविष्यवाणी और स्थिरता के संदर्भ में इसके निष्पादन के वातावरण का प्रतिनिधित्व करता है: एक अनबाउंड थ्रेड निर्माण अंततः रनटाइम संसाधनों को समाप्त कर देगा और आपका आवेदन परिणाम के रूप में अनुभव कर सकता है। , गंभीर प्रदर्शन समस्याएँ जो अनुप्रयोग अस्थिरता को भी जन्म दे सकती हैं।

यह समस्या के सिर्फ एक हिस्से का समाधान है: आप निष्पादित किए जा रहे कार्यों की संख्या को कैप कर रहे हैं, लेकिन उन नौकरियों की संख्या को कैपिंग नहीं कर रहे हैं जिन्हें सबमिट किया जा सकता है और बाद में निष्पादित किया जा सकता है। आवेदन बाद में संसाधन की कमी का अनुभव करेगा, लेकिन यह अंततः इसे अनुभव करेगा यदि प्रस्तुत दर लगातार निष्पादन दर को बढ़ा देती है।

इस समस्या का हल है: वेटिंग कार्यों को आयोजित करने के लिए निष्पादक को एक अवरुद्ध कतार प्रदान करना। यदि कतार भरती है, तो प्रस्तुत कार्य "अस्वीकृत" हो जाएगा। RejectedExecutionHandlerशुरू हो जाती है जब एक काम प्रस्तुत करने को अस्वीकार कर दिया है, और उस की क्यों क्रिया को अस्वीकार कर दिया पिछले आइटम में उद्धृत किया गया। आप अपनी अस्वीकृति नीति को लागू कर सकते हैं या फ्रेमवर्क द्वारा प्रदान की गई अंतर्निहित नीतियों में से किसी एक का उपयोग कर सकते हैं।

डिफ़ॉल्ट अस्वीकृति नीतियों ने निष्पादक को फेंक दिया है RejectedExecutionException। हालाँकि, अन्य अंतर्निहित नीतियाँ आपको:

  • चुपचाप नौकरी छोड़ दें।
  • सबसे पुरानी नौकरी को छोड़ दें और पिछले एक को फिर से शुरू करने का प्रयास करें।
  • कॉलर के थ्रेड पर अस्वीकार किए गए कार्य को निष्पादित करें।

6

स्रोत

एक ThreadPoolExecutor पूल आकार के नियम

एक ThreadPoolExecutor'sपूल के आकार के नियम आम तौर पर याद-समझे जाते हैं, क्योंकि यह उस तरीके से काम नहीं करता है जैसा आप सोचते हैं कि इसे उस तरीके से या जिस तरह से आप इसे चाहते हैं।

इसका उदाहरण लीजिए। थ्रेड पूल का आकार 1 है, कोर पूल का आकार 5 है, अधिकतम पूल का आकार 10 है और कतार 100 है।

सूर्य का रास्ता: जैसा कि धागे में आने वाले अनुरोधों को 5 तक बनाया जाएगा, तब 100 तक पहुंचने तक कार्यों को कतार में जोड़ा जाएगा। जब कतार पूरी हो जाएगी तो नए धागे बनाए जाएंगे maxPoolSize। एक बार जब सभी थ्रेड्स उपयोग में हो जाते हैं और कतार पूर्ण होती है तो कार्य अस्वीकार कर दिया जाएगा। क्यूंकि कतार कम हो जाती है इसलिए सक्रिय थ्रेड्स की संख्या बढ़ जाती है।

उपयोगकर्ता प्रत्याशित तरीका: जैसा कि थ्रेड में आने वाले अनुरोध 10 तक बनाए जाएंगे, तब कार्यों को कतार में जोड़ा जाएगा, जब तक कि यह 100 तक नहीं पहुंच जाता है, जिस समय तक वे अस्वीकार कर दिए जाते हैं। कतार खाली होने तक थ्रेड्स की संख्या अधिकतम नाम बदल जाएगी। जब कतार खाली होती है तो थ्रेड्स तब तक मर जाते हैं जब तक कि वहां नहीं रह जाते corePoolSize

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

यहाँ सरल शब्दों में धागा निर्माण के लिए सूर्य के नियम हैं:

  1. यदि थ्रेड्स की संख्या इससे कम है corePoolSize, तो नया कार्य चलाने के लिए एक नया थ्रेड बनाएं।
  2. यदि थ्रेड्स की संख्या बराबर (या इससे अधिक) है corePoolSize, तो कार्य को कतार में रखें।
  3. यदि कतार पूर्ण है, और थ्रेड्स की संख्या इससे कम है maxPoolSize, तो कार्यों को चलाने के लिए एक नया थ्रेड बनाएं।
  4. यदि कतार भरी हुई है, और थ्रेड्स की संख्या maxPoolSizeकार्य से अधिक या उसके बराबर है , तो कार्य अस्वीकार करें। इसकी लंबी और कमी यह है कि नए धागे केवल तभी बनाए जाते हैं जब कतार भर जाती है, इसलिए यदि आप एक बिना कतार का उपयोग कर रहे हैं, तो धागे की संख्या अधिक नहीं होगी corePoolSize

फुलर स्पष्टीकरण के लिए, इसे घोड़े के मुंह से प्राप्त करें: ThreadPoolExecutorएपीआई प्रलेखन।

एक बहुत अच्छा मंच पोस्ट है जो आपको इस तरह से बात ThreadPoolExecutorकरता है कि कोड उदाहरणों के साथ काम करता है: http://forums.sun.com/thread.jspa?threadID=5401400&tstart=0

अधिक जानकारी: http://forums.sun.com/thread.jspa?threadID=5224557&tstart=450


3

आप javadoc में Corepoolsize और maxpoolsize की परिभाषा पा सकते हैं। http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html

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


3

इस ब्लॉग में अच्छी व्याख्या :

चित्रण

public class ThreadPoolExecutorExample {

    public static void main (String[] args) {
        createAndRunPoolForQueue(new ArrayBlockingQueue<Runnable>(3), "Bounded");
        createAndRunPoolForQueue(new LinkedBlockingDeque<>(), "Unbounded");
        createAndRunPoolForQueue(new SynchronousQueue<Runnable>(), "Direct hand-off");
    }

    private static void createAndRunPoolForQueue (BlockingQueue<Runnable> queue,
                                                                      String msg) {
        System.out.println("---- " + msg + " queue instance = " +
                                                  queue.getClass()+ " -------------");

        ThreadPoolExecutor e = new ThreadPoolExecutor(2, 5, Long.MAX_VALUE,
                                 TimeUnit.NANOSECONDS, queue);

        for (int i = 0; i < 10; i++) {
            try {
                e.execute(new Task());
            } catch (RejectedExecutionException ex) {
                System.out.println("Task rejected = " + (i + 1));
            }
            printStatus(i + 1, e);
        }

        e.shutdownNow();

        System.out.println("--------------------\n");
    }

    private static void printStatus (int taskSubmitted, ThreadPoolExecutor e) {
        StringBuilder s = new StringBuilder();
        s.append("poolSize = ")
         .append(e.getPoolSize())
         .append(", corePoolSize = ")
         .append(e.getCorePoolSize())
         .append(", queueSize = ")
         .append(e.getQueue()
                  .size())
         .append(", queueRemainingCapacity = ")
         .append(e.getQueue()
                  .remainingCapacity())
         .append(", maximumPoolSize = ")
         .append(e.getMaximumPoolSize())
         .append(", totalTasksSubmitted = ")
         .append(taskSubmitted);

        System.out.println(s.toString());
    }

    private static class Task implements Runnable {

        @Override
        public void run () {
            while (true) {
                try {
                    Thread.sleep(1000000);
                } catch (InterruptedException e) {
                    break;
                }
            }
        }
    }
}

आउटपुट:

---- Bounded queue instance = class java.util.concurrent.ArrayBlockingQueue -------------
poolSize = 1, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 3, maximumPoolSize = 5, totalTasksSubmitted = 1
poolSize = 2, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 3, maximumPoolSize = 5, totalTasksSubmitted = 2
poolSize = 2, corePoolSize = 2, queueSize = 1, queueRemainingCapacity = 2, maximumPoolSize = 5, totalTasksSubmitted = 3
poolSize = 2, corePoolSize = 2, queueSize = 2, queueCapacity = 1, maximumPoolSize = 5, totalTasksSubmitted = 4
poolSize = 2, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 5
poolSize = 3, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 6
poolSize = 4, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 7
poolSize = 5, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 8
Task rejected = 9
poolSize = 5, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 9
Task rejected = 10
poolSize = 5, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 10
--------------------

---- Unbounded queue instance = class java.util.concurrent.LinkedBlockingDeque -------------
poolSize = 1, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 2147483647, maximumPoolSize = 5, totalTasksSubmitted = 1
poolSize = 2, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 2147483647, maximumPoolSize = 5, totalTasksSubmitted = 2
poolSize = 2, corePoolSize = 2, queueSize = 1, queueRemainingCapacity = 2147483646, maximumPoolSize = 5, totalTasksSubmitted = 3
poolSize = 2, corePoolSize = 2, queueSize = 2, queueRemainingCapacity = 2147483645, maximumPoolSize = 5, totalTasksSubmitted = 4
poolSize = 2, corePoolSize = 2, queueSize = 3, queueRemainingCapacity = 2147483644, maximumPoolSize = 5, totalTasksSubmitted = 5
poolSize = 2, corePoolSize = 2, queueSize = 4, queueRemainingCapacity = 2147483643, maximumPoolSize = 5, totalTasksSubmitted = 6
poolSize = 2, corePoolSize = 2, queueSize = 5, queueRemainingCapacity = 2147483642, maximumPoolSize = 5, totalTasksSubmitted = 7
poolSize = 2, corePoolSize = 2, queueSize = 6, queueRemainingCapacity = 2147483641, maximumPoolSize = 5, totalTasksSubmitted = 8
poolSize = 2, corePoolSize = 2, queueSize = 7, queueRemainingCapacity = 2147483640, maximumPoolSize = 5, totalTasksSubmitted = 9
poolSize = 2, corePoolSize = 2, queueSize = 8, queueRemainingCapacity = 2147483639, maximumPoolSize = 5, totalTasksSubmitted = 10
--------------------

---- Direct hand-off queue instance = class java.util.concurrent.SynchronousQueue -------------
poolSize = 1, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 1
poolSize = 2, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 2
poolSize = 3, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 3
poolSize = 4, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 4
poolSize = 5, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 5
Task rejected = 6
poolSize = 5, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 6
Task rejected = 7
poolSize = 5, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 7
Task rejected = 8
poolSize = 5, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 8
Task rejected = 9
poolSize = 5, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 9
Task rejected = 10
poolSize = 5, corePoolSize = 2, queueSize = 0, queueRemainingCapacity = 0, maximumPoolSize = 5, totalTasksSubmitted = 10
--------------------


Process finished with exit code 0

1

पुस्तक से जावा संक्षिप्तता अनिवार्य :

CorePoolSize : The ThreadPoolExecutor में एक विशेषता है CorePoolSize, जो यह निर्धारित करती है कि कतार के पूर्ण होने पर ही नए थ्रेड शुरू होने तक कितने थ्रेड शुरू होंगे।

मैक्सपूलसाइज़ : यह विशेषता निर्धारित करती है कि अधिकतम कितने धागे शुरू किए गए हैं। आप इसे इंटेगर में सेट कर सकते हैं। MAX_VALUE कोई ऊपरी सीमा नहीं है


0

java.util.concurrent.ThreadPoolExecutor

  public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        /*
         * Proceed in 3 steps:
         *
         * 1. If fewer than corePoolSize threads are running, try to
         * start a new thread with the given command as its first
         * task.  The call to addWorker atomically checks runState and
         * workerCount, and so prevents false alarms that would add
         * threads when it shouldn't, by returning false.
         *
         * 2. If a task can be successfully queued, then we still need
         * to double-check whether we should have added a thread
         * (because existing ones died since last checking) or that
         * the pool shut down since entry into this method. So we
         * recheck state and if necessary roll back the enqueuing if
         * stopped, or start a new thread if there are none.
         *
         * 3. If we cannot queue task, then we try to add a new
         * thread.  If it fails, we know we are shut down or saturated
         * and so reject the task.
         */
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

0

ThreadPoolExecutorजब किसी नए कार्य को प्रस्तुत किया जाता है , तो उसके आंतरिक व्यवहार को समझने से मुझे यह समझने में मदद मिलती है कि कैसे corePoolSizeऔर maximumPoolSizeअलग - अलग हैं।

करते हैं:

  • Nपूल में धागे की संख्या हो getPoolSize()। सक्रिय धागे + निष्क्रिय धागे।
  • T निष्पादक / पूल को प्रस्तुत कार्यों की राशि हो।
  • C, मुख्य पूल आकार हो getCorePoolSize()नए कार्यों को कतार में जाने से पहले आने वाले कार्यों के लिए प्रति पूल कितने धागे बनाए जा सकते हैं
  • Mअधिकतम पूल आकार हो getMaximumPoolSize()। थ्रेड्स की अधिकतम राशि पूल आवंटित कर सकती है।

ThreadPoolExecutorजब नया कार्य प्रस्तुत किया जाता है तो जावा में व्यवहार :

  • इसके लिए N <= C, निष्क्रिय थ्रेड्स को नए इनकमिंग कार्य को असाइन नहीं किया जाता है, इसके बजाय एक नया थ्रेड बनाया जाता है।
  • के लिए N > Cऔर यदि निष्क्रिय थ्रेड्स हैं तो वहां नया कार्य सौंपा गया है।
  • के लिए N > Cऔर अगर कोई निष्क्रिय धागे हैं, नए कार्यों को कतार में डाल दिया जाता है। यहां कोई नया निर्माण नहीं हुआ।
  • जब कतार भर जाती है , तो हम नए सूत्र बनाते हैं M। यदि Mपहुंच गया है, तो हम कार्यों को अस्वीकार करते हैं। यहाँ नहीं करना महत्वपूर्ण है कि जब तक कतार पूरी नहीं हो जाती तब तक हम नए धागे नहीं बनाते हैं!

सूत्रों का कहना है:

उदाहरण

का एक कतार क्षमता के साथ corePoolSize = 0और उदाहरण के साथ ।maximumPoolSize = 1050

यह पूल में एक एकल सक्रिय धागे का परिणाम देगा जब तक कि कतार में 50 आइटम न हों।

executor.execute(task #1):

before task #1 submitted to executor: java.util.concurrent.ThreadPoolExecutor@c52dafe[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]

after task #1 submitted to executor: java.util.concurrent.ThreadPoolExecutor@c52dafe[Running, pool size = 1, active threads = 1, queued tasks = 1, completed tasks = 0]

[task #1 immediately queued and kicked in b/c the very first thread is created when `workerCountOf(recheck) == 0`]

execute(task #2):

before task #2 submitted to executor: java.util.concurrent.ThreadPoolExecutor@c52dafe[Running, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]

after task #2 submitted to executor: java.util.concurrent.ThreadPoolExecutor@c52dafe[Running, pool size = 1, active threads = 1, queued tasks = 1, completed tasks = 0]

[task #2 not starting before #1 is done]

... executed a few tasks...

execute(task #19)

before task #19 submitted to executor: java.util.concurrent.ThreadPoolExecutor@735afe38[Running, pool size = 1, active threads = 1, queued tasks = 17, completed tasks = 0]

after task #19 submitted to executor: java.util.concurrent.ThreadPoolExecutor@735afe38[Running, pool size = 1, active threads = 1, queued tasks = 18, completed tasks = 0]

...

execute(task #51)

before task submitted to executor: java.util.concurrent.ThreadPoolExecutor@735afe38[Running, pool size = 1, active threads = 1, queued tasks = 50, completed tasks = 0]

after task submitted to executor: java.util.concurrent.ThreadPoolExecutor@735afe38[Running, pool size = 2, active threads = 2, queued tasks = 50, completed tasks = 0]

Queue is full.
A new thread was created as the queue was full.

का एक कतार क्षमता के साथ corePoolSize = 10और उदाहरण के साथ ।maximumPoolSize = 1050

इसके परिणामस्वरूप पूल में 10 सक्रिय धागे होंगे। जब कतार में 50 आइटम होंगे, तो कार्यों को अस्वीकार कर दिया जाएगा।

execute(task #1)

before task #1 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]

after task #1 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]

execute(task #2)

before task #2 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]

after task #2 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0]

execute(task #3)

before task #3 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0]

after task #3 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 0]

... executed a few tasks...

execute(task #11)

before task #11 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 10, active threads = 10, queued tasks = 0, completed tasks = 0]

after task #11 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 10, active threads = 10, queued tasks = 1, completed tasks = 0]

... executed a few tasks...

execute(task #51)
before task #51 submitted to executor: java.util.concurrent.ThreadPoolExecutor@32d9e072[Running, pool size = 10, active threads = 10, queued tasks = 50, completed tasks = 0]

Task was rejected as we have reached `maximumPoolSize`. 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.