2013-03-15 36 views
2

我刚刚读取this article,并认为如果Runnable的抛出异常并退出,threadpool可能会耗尽工作线程。我做了一个小代码并检查,但池大小没有变化。线程抛出RuntimeException - 对线程池的影响

public class ThreadPoolTest { 

public static void main(String[] args) throws InterruptedException { 
    ThreadPoolExecutor tp = new ThreadPoolExecutor(1, 1, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1)); 
    Thread.sleep(1000); 
    System.out.println(tp.getPoolSize()); 
    tp.execute(new Runnable(){ 

     @Override 
     public void run() { 
      System.out.println("Executing & Throwing"); 
      throw new NullPointerException(); 
     } 

    }); 
    Thread.sleep(1000); 
    System.out.println(tp.getPoolSize()); 
    tp.execute(new Runnable(){ 

     @Override 
     public void run() { 
      System.out.println("Executing & Throwing"); 
      throw new NullPointerException(); 
     } 

    }); 
    Thread.sleep(1000); 
    System.out.println(tp.getPoolSize()); 
    tp.shutdown(); 
} 

}

输出我得到

0 
Exception in thread "pool-1-thread-1" java.lang.NullPointerException 
    at threads.ThreadPoolTest$1.run(ThreadPoolTest.java:18) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at java.lang.Thread.run(Unknown Source) 
Executing & Throwing 
1 
Exception in thread "pool-1-thread-2" java.lang.NullPointerException 
    at threads.ThreadPoolTest$2.run(ThreadPoolTest.java:29) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at java.lang.Thread.run(Unknown Source) 
Executing & Throwing 
1 

这是一个关于Java 7中是否有线程池的实现任何Java在文章中指出这是脆弱?

+0

据我所知,ThreadPoolExecutor的产生一个新的工人来维持游泳池大小。 – 2013-03-15 10:04:41

回答

1

阅读这篇文章,其要点是写得不好的线程池可能会遇到这个问题。事实上,任何创建线程的应用程序都不会处理该线程未捕获的异常。

我希望线程池的任何有信誉的来源以某种方式处理这种情况。值得肯定的是,我将包括Oracle提供的解决方案。我怀疑如果某人手动编写线程池并且他们缺乏经验,那么他们会编写一个不太稳健的解决方案。

1

文章说:

标准的线程池允许未捕获的任务异常终止池中的线程

是哪种情况。稍微修改一下你的代码就会发现,当前一个由于异常而死的时候,ThreadPool会创建一个新的线程。

作为一条评论,您一般会使用submit方法,并尝试在返回的Future上尝试get以查看是否抛出了异常。

输出:

0 
Creating new thread 
Executing & Throwing 
Creating new thread 
Exception in thread "Thread-0" java.lang.NullPointerException 
    at javaapplication4.Test2$2.run(Test2.java:47) 
    .... 
1 
Executing & Throwing 
Creating new thread 
Exception in thread "Thread-1" java.lang.NullPointerException 
    at javaapplication4.Test2$3.run(Test2.java:56) 
    .... 
1 

代码:当在工作线程工人完成和其他一些工人取代其位置的任何RuntimeException的

public static void main(String[] args) throws InterruptedException { 
    ThreadPoolExecutor tp = new ThreadPoolExecutor(1, 1, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1), new ThreadFactory() { 

     @Override 
     public Thread newThread(Runnable r) { 
      System.out.println("Creating new thread"); 
      return new Thread(r); 
     } 
    }); 
    Thread.sleep(1000); 
    System.out.println(tp.getPoolSize()); 
    tp.execute(new Runnable() { 
     @Override 
     public void run() { 
      System.out.println("Executing & Throwing"); 
      throw new NullPointerException(); 
     } 
    }); 
    Thread.sleep(100); 
    System.out.println(tp.getPoolSize()); 
    tp.execute(new Runnable() { 
     @Override 
     public void run() { 
      System.out.println("Executing & Throwing"); 
      throw new NullPointerException(); 
     } 
    }); 
    Thread.sleep(100); 
    System.out.println(tp.getPoolSize()); 
    tp.shutdown(); 
}