2010-06-17 9 views
9

का उपयोग करते समय अटक गया है, मैं कुछ अनुप्रयोगों पर काम कर रहा हूं और विभिन्न कार्यों को संभालने के लिए थ्रेडपूल एक्स्सेलर का उपयोग कर रहा हूं। कुछ अवधि के बाद ThreadPoolExecutor अटक गया है। इसे सरल वातावरण में अनुकरण करने के लिए, मैंने एक साधारण कोड लिखा है जहां मैं इस मुद्दे को अनुकरण करने में सक्षम हूं।Java ThreadPoolExecutor ArrayBlockingQueue

import java.util.concurrent.ArrayBlockingQueue; 
import java.util.concurrent.RejectedExecutionHandler; 
import java.util.concurrent.ThreadPoolExecutor; 
import java.util.concurrent.TimeUnit; 

public class MyThreadPoolExecutor { 
    private int poolSize = 10; 
    private int maxPoolSize = 50; 
    private long keepAliveTime = 10; 
    private ThreadPoolExecutor threadPool = null; 
    private final ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(
      100000); 

    public MyThreadPoolExecutor() { 
     threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize, 
       keepAliveTime, TimeUnit.SECONDS, queue); 
     threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() { 

      @Override 
      public void rejectedExecution(Runnable runnable, 
        ThreadPoolExecutor threadPoolExecutor) { 
       System.out 
         .println("Execution rejected. Please try restarting the application."); 
      } 

     }); 
    } 

    public void runTask(Runnable task) { 
     threadPool.execute(task); 
    } 

    public void shutDown() { 
     threadPool.shutdownNow(); 
    } 
    public ThreadPoolExecutor getThreadPool() { 
     return threadPool; 
    } 

    public void setThreadPool(ThreadPoolExecutor threadPool) { 
     this.threadPool = threadPool; 
    } 

    public static void main(String[] args) { 
     MyThreadPoolExecutor mtpe = new MyThreadPoolExecutor(); 
     for (int i = 0; i < 1000; i++) { 
      final int j = i; 
      mtpe.runTask(new Runnable() { 

       @Override 
       public void run() { 
        System.out.println(j); 
       } 

      }); 
     } 
    } 
} 

इस कोड को कुछ बार निष्पादित करने का प्रयास करें। यह आम तौर पर कंसोल पर संख्या को प्रिंट करता है और जब सभी धागे समाप्त होते हैं, तो यह मौजूद है। लेकिन कई बार, यह सभी कार्य समाप्त हो गया और फिर समाप्त नहीं हो रहा है।

MyThreadPoolExecutor [Java Application] 
    MyThreadPoolExecutor at localhost:2619 (Suspended) 
     Daemon System Thread [Attach Listener] (Suspended) 
     Daemon System Thread [Signal Dispatcher] (Suspended)  
     Daemon System Thread [Finalizer] (Suspended)  
      Object.wait(long) line: not available [native method] 
      ReferenceQueue<T>.remove(long) line: not available  
      ReferenceQueue<T>.remove() line: not available  
      Finalizer$FinalizerThread.run() line: not available 
     Daemon System Thread [Reference Handler] (Suspended)  
      Object.wait(long) line: not available [native method] 
      Reference$Lock(Object).wait() line: 485 
      Reference$ReferenceHandler.run() line: not available  
     Thread [pool-1-thread-1] (Suspended)  
      Unsafe.park(boolean, long) line: not available [native method] 
      LockSupport.park(Object) line: not available  
      AbstractQueuedSynchronizer$ConditionObject.await() line: not available 
      ArrayBlockingQueue<E>.take() line: not available 
      ThreadPoolExecutor.getTask() line: not available  
      ThreadPoolExecutor$Worker.run() line: not available 
      Thread.run() line: not available  
     Thread [pool-1-thread-2] (Suspended)  
      Unsafe.park(boolean, long) line: not available [native method] 
      LockSupport.park(Object) line: not available  
      AbstractQueuedSynchronizer$ConditionObject.await() line: not available 
      ArrayBlockingQueue<E>.take() line: not available 
      ThreadPoolExecutor.getTask() line: not available  
      ThreadPoolExecutor$Worker.run() line: not available 
      Thread.run() line: not available  
     Thread [pool-1-thread-3] (Suspended)  
      Unsafe.park(boolean, long) line: not available [native method] 
      LockSupport.park(Object) line: not available  
      AbstractQueuedSynchronizer$ConditionObject.await() line: not available 
      ArrayBlockingQueue<E>.take() line: not available 
      ThreadPoolExecutor.getTask() line: not available  
      ThreadPoolExecutor$Worker.run() line: not available 
      Thread.run() line: not available  
     Thread [pool-1-thread-4] (Suspended)  
      Unsafe.park(boolean, long) line: not available [native method] 
      LockSupport.park(Object) line: not available  
      AbstractQueuedSynchronizer$ConditionObject.await() line: not available 
      ArrayBlockingQueue<E>.take() line: not available 
      ThreadPoolExecutor.getTask() line: not available  
      ThreadPoolExecutor$Worker.run() line: not available 
      Thread.run() line: not available  
     Thread [pool-1-thread-6] (Suspended)  
      Unsafe.park(boolean, long) line: not available [native method] 
      LockSupport.park(Object) line: not available  
      AbstractQueuedSynchronizer$ConditionObject.await() line: not available 
      ArrayBlockingQueue<E>.take() line: not available 
      ThreadPoolExecutor.getTask() line: not available  
      ThreadPoolExecutor$Worker.run() line: not available 
      Thread.run() line: not available  
     Thread [pool-1-thread-8] (Suspended)  
      Unsafe.park(boolean, long) line: not available [native method] 
      LockSupport.park(Object) line: not available  
      AbstractQueuedSynchronizer$ConditionObject.await() line: not available 
      ArrayBlockingQueue<E>.take() line: not available 
      ThreadPoolExecutor.getTask() line: not available  
      ThreadPoolExecutor$Worker.run() line: not available 
      Thread.run() line: not available  
     Thread [pool-1-thread-5] (Suspended)  
      Unsafe.park(boolean, long) line: not available [native method] 
      LockSupport.park(Object) line: not available  
      AbstractQueuedSynchronizer$ConditionObject.await() line: not available 
      ArrayBlockingQueue<E>.take() line: not available 
      ThreadPoolExecutor.getTask() line: not available  
      ThreadPoolExecutor$Worker.run() line: not available 
      Thread.run() line: not available  
     Thread [pool-1-thread-10] (Suspended) 
      Unsafe.park(boolean, long) line: not available [native method] 
      LockSupport.park(Object) line: not available  
      AbstractQueuedSynchronizer$ConditionObject.await() line: not available 
      ArrayBlockingQueue<E>.take() line: not available 
      ThreadPoolExecutor.getTask() line: not available  
      ThreadPoolExecutor$Worker.run() line: not available 
      Thread.run() line: not available  
     Thread [pool-1-thread-9] (Suspended)  
      Unsafe.park(boolean, long) line: not available [native method] 
      LockSupport.park(Object) line: not available  
      AbstractQueuedSynchronizer$ConditionObject.await() line: not available 
      ArrayBlockingQueue<E>.take() line: not available 
      ThreadPoolExecutor.getTask() line: not available  
      ThreadPoolExecutor$Worker.run() line: not available 
      Thread.run() line: not available  
     Thread [pool-1-thread-7] (Suspended)  
      Unsafe.park(boolean, long) line: not available [native method] 
      LockSupport.park(Object) line: not available  
      AbstractQueuedSynchronizer$ConditionObject.await() line: not available 
      ArrayBlockingQueue<E>.take() line: not available 
      ThreadPoolExecutor.getTask() line: not available  
      ThreadPoolExecutor$Worker.run() line: not available 
      Thread.run() line: not available  
     Thread [DestroyJavaVM] (Suspended) 
    C:\Program Files\Java\jre1.6.0_07\bin\javaw.exe (Jun 17, 2010 10:42:33 AM) 

अपने वास्तविक आवेदन में, ThreadPoolExecutor धागे इस राज्य में जाने के लिए और फिर इसे जवाब बंद हो जाता है: धागा डंप इस प्रकार है।

सादर, रवि राव

+0

एक विचार यह है कि आप मेरा पसंदीदा पसंदीदा एक्जिक्यूटर्स सेवा का प्रयास करते हैं। –

+0

@ लार्स एंडरेन, एक थ्रेडपूलएक्सएटर एक निष्पादक सेवा है। निष्पादक सेवा बस एक इंटरफ़ेस है। जावा 1.5 लाइब्रेरी में, ThreadPoolExecutor निष्पादक सेवा इंटरफ़ेस का एकमात्र प्रत्यक्ष कार्यान्वयन है। एक सार तत्वकर्ता सेवा और एक प्रतिनिधिमंडल सेवा है जो स्टैंड-अलोन कार्यात्मक कक्षाएं नहीं हैं। इसके अलावा, एक SheceduledExecutorService इंटरफ़ेस है जो निष्पादक सेवा प्रदान करता है और इसमें एक ठोस ठोस कार्यान्वयन है। –

उत्तर

9

अपने main विधि में, आप mtpe.shutdown() फोन कभी नहीं। एक ThreadPoolExecutor अपने corePoolSize को अनिश्चित काल तक जीवित रखने का प्रयास करेगा। कभी-कभी, आप भाग्यशाली हो जाते हैं और आपके पास corePoolSize से अधिक धागे जीवित होते हैं, इसलिए प्रत्येक कार्यकर्ता धागा एक सशर्त तर्क शाखा में जाएगा जो इसे 10 सेकंड की आपकी निर्दिष्ट टाइमआउट अवधि के बाद समाप्त कर देता है। हालांकि, जैसा कि आपने देखा है, कभी-कभी ऐसा नहीं होता है इसलिए निष्पादक में प्रत्येक थ्रेड ArrayBlockingQueue.take() पर अवरुद्ध होगा और एक नया कार्य प्रतीक्षा करेगा।

इसके अलावा, कृपया ध्यान दें, ExecutorService.shutdown() और ExecutorService.shutdownNow() के बीच एक महत्वपूर्ण अंतर है। यदि आप execorService.shutdownNow() को कॉल करते हैं, क्योंकि आपके रैपर कार्यान्वयन से संकेत मिलता है, तो आप कुछ ऐसे कार्यों को छोड़ देंगे जिन्हें निष्पादन के लिए असाइन नहीं किया गया है।

अपडेट: मेरा मूल उत्तर के बाद, ThreadPoolExecutor कार्यान्वयन बदल गया है कि मूल पोस्ट में प्रोग्राम कभी बाहर नहीं निकलना चाहिए।