37

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

नीचे कोड जो ExecutorService उपयोग कर रहा है -

public class MultithreadingExample { 

    public static void main(String[] args) throws InterruptedException { 

     ExecutorService executor = Executors.newFixedThreadPool(20); 
     for (int i = 0; i < 100; i++) { 
      executor.submit(new NewTask()); 
     } 

     executor.shutdown(); 
     executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
    } 
} 

class NewTask implements Runnable { 

    @Override 
    public void run() { 
     //Measure the end to end latency of my client code 
    } 
} 

समस्या वक्तव्य: -

अब मैं इंटरनेट पर कुछ लेख पढ़ रहा था। मैंने पाया कि

ThreadPoolExecutor भी है। तो मुझे उलझन में आया कि मुझे किस का उपयोग करना चाहिए।

अगर मैं अपने ऊपर कोड from-

ExecutorService executor = Executors.newFixedThreadPool(20); 
    for (int i = 0; i < 100; i++) { 
     executor.submit(new NewTask()); 
    } 

हैं-

BlockingQueue<Runnable> threadPool = new LinkedBlockingQueue<Runnable>(); 

ThreadPoolExecutor tpExecutor = new ThreadPoolExecutor(20, 2000, 0L, TimeUnit.MILLISECONDS, threadPool); 

tpExecutor.prestartAllCoreThreads(); 

    for (int i = 0; i < 100; i++) { 
     tpExecutor.execute(new NewTask()); 
    } 

तो है कि कोई फर्क होगा की जगह? मैं समझने की कोशिश कर रहा हूं कि मेरे मूल कोड के बीच क्या अंतर है जो ExecutorService और नया कोड है, जिसे मैंने चिपकाया है जो ThreadPoolExectuor का उपयोग कर रहा है? मेरे कुछ साथी साथी ने कहा कि दूसरा (थ्रेडपूलएक्सएटर) उपयोग करने का सही तरीका है?

क्या कोई मेरे लिए इस चीज़ को स्पष्ट कर सकता है? सहायता के लिए धन्यवाद।

उत्तर

19

तो इससे कोई फर्क पड़ता है?

यह आपके कोड को थोड़ा लाभ के लिए अधिक जटिल बना देगा।

मैं समझने की कोशिश कर रहा हूं कि मेरे मूल कोड के बीच क्या अंतर है जो निष्पादक सेवा और नया कोड का उपयोग कर रहा है, जिसे मैंने चिपकाया था जो थ्रेडपूलएक्सक्वायर का उपयोग कर रहा है?

कुछ भी नहीं के बगल में। Executors वास्तविक काम करने के लिए थ्रेडपूल एक्स्सेलर बनाता है।

मेरी कुछ टीम के साथी ने कहा कि दूसरा (थ्रेडपूलएक्सएटर) उपयोग करने का सही तरीका है?

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

+0

आपने कुछ छोटे लाभ के बारे में बात की? यह सब किस बारे में हैं? और दृश्य के पीछे निष्पादकों ने ThreadPoolExecutor को सही कहा? लेकिन मेरा मानना ​​है कि यह अनबाउंड कतार का उपयोग करता है जो मुझे लगता है कि थोड़ा धीमा है? अगर मैं ग़लत हूं तो मेरी गलती सुझाएं। –

+0

थोड़ा लाभ यह है कि आप कन्स्ट्रक्टर तर्कों के साथ खेल सकते हैं, लेकिन आमतौर पर यह एक अच्छा विचार नहीं है। आपने एक ही असंबद्ध कतार प्रदान की है, इसलिए मुझे आपका बिंदु नहीं दिख रहा है। यदि यह धीमा था, तो डिजाइनर इसका उपयोग क्यों करेंगे? –

+0

LinkedBoundedQueue का उपयोग करने में एक लागत है। इस तथ्य के साथ इसका कोई लेना-देना नहीं है कि यह असंबद्ध है और धागे के बीच गुजरने के कार्यों की तुलना में यह बहुत छोटा है, जो मुझे लगता है कि आप बहुत चिंतित नहीं हैं। –

7
  1. Executors#newFixedThreadPool(int nThreads)

    ExecutorService executor = Executors.newFixedThreadPool(20); 
    

मूल रूप से

return new ThreadPoolExecutor(20, 20, 
            0L, TimeUnit.MILLISECONDS, 
            new LinkedBlockingQueue<Runnable>()); 

2 है।

BlockingQueue<Runnable> threadPool = new LinkedBlockingQueue<Runnable>(); 
ThreadPoolExecutor tpExecutor = new ThreadPoolExecutor(20, 2000, 0L, 
    TimeUnit.MILLISECONDS, threadPool); 

दूसरे मामले में, तुम सिर्फ 2000 तक maxPoolSize है, जो मुझे शक है आप की आवश्यकता होगी बढ़ रही हैं।

public static ExecutorService newFixedThreadPool(int nThreads) { 
    return new ThreadPoolExecutor(nThreads, nThreads, 
            0L, TimeUnit.MILLISECONDS, 
            new LinkedBlockingQueue<Runnable>()); 
} 

यह आंतरिक रूप से डिफ़ॉल्ट कॉन्फ़िगरेशन के साथ ThreadPoolExecutor वर्ग का उपयोग करता है के रूप में आप ऊपर देख सकते हैं:

58

यहाँ Executors.newFixedThreadPool का स्रोत है। अब ऐसे परिदृश्य हैं जहां LinkedBlockingQueue की बजाय डिफ़ॉल्ट कॉन्फ़िगरेशन उपयुक्त नहीं है, प्राथमिकता कतार का उपयोग करने की आवश्यकता है। ऐसे मामलों में कॉलर सीधे इसे तत्काल ThreadPoolExecutor पर काम कर सकता है और इसे वांछित कॉन्फ़िगरेशन पास कर सकता है।

4

मेरा मानना ​​है कि एक और लाभ अस्वीकृति हैडलर के साथ है। मुझे गलत करें अगर

1

GC out of memory exception के 2 दिनों के बाद, ThreadPoolExecutor ने मेरी जान बचाई। :)

के रूप में बालाजी ने कहा,

[..] एक और लाभ RejectionHandler के साथ है।

मेरे मामले में मैं RejectedExecutionException का एक बहुत था और (पालन) को निर्दिष्ट छोड़ें नीति मेरी सभी समस्याओं को हल।

private ThreadPoolExecutor executor = new ThreadPoolExecutor(1, cpus, 1, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new ThreadPoolExecutor.DiscardPolicy()); 

लेकिन सावधान रहें! यह केवल तभी काम करता है जब आप को निष्पादित करने की आवश्यकता नहीं है आपके द्वारा निष्पादक को सबमिट किए गए थ्रेड।

अधिक जानकारी के लिए के बारे में ThreadPoolExecutorDarren's answer

0

पहले उदाहरण में पर एक नज़र डालें, आप नीचे दिए गए बयान

ExecutorService executor = Executors.newFixedThreadPool(20); 

दूसरे उदाहरण में से सिर्फ 20 धागे बना लेते हैं तो धागा सीमा में सीमा निर्धारित किया है 20 to 2000के बीच

ThreadPoolExecutor tpExecutor = new ThreadPoolExecutor(20, 2000, 0L, 
            TimeUnit.MILLISECONDS,threadPool); 

अधिक धागे प्रक्रिया के लिए उपलब्ध हैं ssing। लेकिन आपने कार्य कतार को असंबद्ध कतार के रूप में कॉन्फ़िगर किया है।

ThreadPoolExecutor अधिक प्रभावी होगा यदि आपने कई या सभी पैरामीटर को अनुकूलित किया है। जब आप max capacity for workQueue सेट और कार्यों, जो निर्वाहक को प्रस्तुत किया गया है की संख्या एक से अधिक workQueue क्षमता हैं

ThreadPoolExecutor(int corePoolSize, 
       int maximumPoolSize, 
       long keepAliveTime, 
       TimeUnit unit, 
       BlockingQueue<Runnable> workQueue, 
       ThreadFactory threadFactory, 
       RejectedExecutionHandler handler) 

RejectedExecutionHandler उपयोगी होगा।

अधिक जानकारी के लिए ThreadPoolExecutor में अस्वीकृत कार्य अनुभाग पर एक नज़र डालें।

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