2015-11-17 12 views
5

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

public class BackgroundProcesses { 

    public static void main(String[] args) throws InterruptedException, ExecutionException { 
     //ExecutorService threadPool2 = Executors.newCachedThreadPool(); 
     ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); 
     for (int i = 0; i < 800; i++) { 
      Callable<String> task = new Task(); 
      threadPool.submit(task); 
     } 
    } 
} 

class Task implements Callable<String> { 

    @Override 
    public String call() throws Exception { 
     Thread.sleep(100); 
     System.out.println(Thread.currentThread().getName() + " is ready"); 
     return ""; 
    } 
} 

अगर मैं कोड को चलाने मैं उत्पादन:

pool-1-thread-1 is ready 
pool-1-thread-2 is ready 
pool-1-thread-1 is ready 
pool-1-thread-2 is ready 
... 

केवल 2 धागे सब काम कर रहे हैं और कोई नया कार्यकर्ता धागे पूल में जुड़ जाते हैं अर्थ। यदि कार्य कतार में इंतजार कर रहे हैं (मेरे मामले में 10 तक) तो थ्रेडपूल अधिक धागे नहीं पैदा करना चाहिए?

मैं Executors.newCachedThreadPool() का उपयोग नहीं करना चाहता क्योंकि इसकी व्यावहारिक रूप से अधिकतम धागे पर कोई ऊपरी सीमा नहीं है और इसमें corePoolSize 0. है। मैं बेहतर प्रतिक्रिया के लिए हर समय कुछ धागे तैयार करना चाहता हूं।

----- संपादित 1 -----

उत्तर के लिए अलेक्सी धन्यवाद। कतार में क्षमता निर्धारित करने से यह अपेक्षित व्यवहार कर रहा है, लेकिन अब मुझे एक नई समस्या है।

पृष्ठभूमि कार्यों की मात्रा बहुत भिन्न होती है। अधिकांश समय 0 लेकिन छोटी अवधि के लिए 50 समवर्ती कार्यों तक जा सकता है। इसे संभालने का एक प्रभावी तरीका क्या होगा? ध्यान रखें कि अधिकांश पृष्ठभूमि कार्य अल्पकालिक (< 1 एस) होंगे लेकिन कुछ लंबे समय तक रहने वाले कार्यों (> 1min) भी होंगे।

अगर मैं इस तरह मेरी ThreadPool सेट अप:

ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10)); 

मैं सबसे अधिक संभावना व्यस्त उपयोग के साथ RejectedExecutionException मिल जाएगा। लेकिन अगर मैं इस तरह अप ThreadPool सेट:

ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(200)); 

फिर कोई नया कार्यकर्ता धागे कभी जोड़ दिया जाएगा क्योंकि कतार बाहर अधिकतम नहीं होगा।

सीपीयू में कम से कम 4 कोर हैं इसलिए यह मेरी राय में अपमानजनक होगा। और अधिकांश समय में कोई भी पृष्ठभूमि कार्य नहीं होता है (80% समय), इसलिए एक निश्चित थ्रेड पूल भी मेरी राय में अपमानजनक होगा।

उत्तर

4

ThreadPoolExecutor जावाडोक का कहना है:

जब कोई नया कार्य निष्पादित (Runnable) विधि में प्रस्तुत किया जाता है, और कम corePoolSize धागे से चल रहे हैं, एक नया धागा लिए बनाई गई है अनुरोध को पूरा करने, यहां तक ​​कि अन्य अगर कार्यकर्ता धागे निष्क्रिय हैं। वहाँ corePoolSize की तुलना में अधिक है, लेकिन maximumPoolSize धागे चल रहा है, एक नया धागा बनाया जाएगा की तुलना में कम कर रहे हैं केवल यदि कतार भर गई है

क्योंकि यह संख्या पर एक ऊपरी बाध्य नहीं है आपका LinkedBlockingQueue, कभी नहीं भरा है तत्वों का। बदलना new LinkedBlockingQueue() से new LinkedBlockingQueue(10) इसे हल करेगा।

+0

इसे साफ़ करने के लिए धन्यवाद। लेकिन अब मुझे अस्वीकृति एक्सेक्यूशन अपवाद (पूल आकार = 10, सक्रिय धागे = 10, कतारबद्ध कार्य = 10) मिल रहा है क्योंकि कतार भर जाती है और सभी सक्रिय धागे भी उपयोग किए जाते हैं। –

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