我刚刚阅读this article并认为如果Runnable
抛出异常并退出,则线程池可能会耗尽工作线程。我做了一个小代码并检查,但是池化没有变化。
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 Threadpool实现?
答案 0 :(得分:1)
阅读文章,要点是写得不好的线程池可能会遇到这个问题。实际上,任何创建线程的应用程序都不会/不能处理来自该线程的未捕获异常。
我希望任何有信誉的线程池源都能以某种方式处理这种情况。通过信誉良好,我将包括Oracle源解决方案。我怀疑如果有人手动编写一个线程池,他们缺乏经验,那么他们就会编写一个不那么强大的解决方案。
答案 1 :(得分: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
代码:
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();
}