java 线程抛出 RuntimeException - 对线程池的影响
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15429227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Threads throwing RuntimeException - Impact on Threadpool
提问by R Kaja Mohideen
I just read this articleand thought that threadpool may run out of worker threads if the Runnable
's throw exception and exit. I did a small code and checked, but the poolsize didn't vary.
我刚刚读了这篇文章,认为如果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();
}
}
}
Output I got was
我得到的输出是
0
Exception in thread "pool-1-thread-1" java.lang.NullPointerException
at threads.ThreadPoolTest.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.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
This is on Java 7. Is there any java Threadpool implementation which is vulnerable as stated in the article?
这是在 Java 7 上。是否有文章中所述的易受攻击的 Java 线程池实现?
采纳答案by Brian Agnew
Reading the article, the gist is that a poorly written thread pool can suffer from this problem. In fact, any application that creates a thread and doesn't/can't handle an uncaught exception from that thread.
阅读这篇文章,要点是写得不好的线程池可能会遇到这个问题。事实上,任何创建线程但不/不能处理来自该线程的未捕获异常的应用程序。
I'd expect any reputable source of a thread pool to handle this scenario in some fashion. By reputable, I would include the Oracle-sourced solutions. I suspect if someone was hand-coding a thread pool and they lacked experience then they'd write a less-robust solution.
我希望线程池的任何有信誉的来源都能以某种方式处理这种情况。有信誉的,我会包括来自 Oracle 的解决方案。我怀疑如果有人手动编码线程池并且他们缺乏经验,那么他们会编写一个不太可靠的解决方案。
回答by assylias
The article states:
文章指出:
The standard thread pools allow an uncaught task exception to terminate the pool thread
标准线程池允许未捕获的任务异常终止池线程
which is the case. A slightly amended version of your code shows that the ThreadPool will create a new thread when the previous has died due to an exception.
情况就是这样。对您的代码稍作修改的版本显示,当前一个线程因异常而死亡时,ThreadPool 将创建一个新线程。
As a side comment, you would in general use the submit
method, and try to get
on the returned Future to see if an exception has be thrown.
作为旁注,您通常会使用该submit
方法,并尝试get
在返回的 Future 上查看是否已抛出异常。
Output:
输出:
0
Creating new thread
Executing & Throwing
Creating new thread
Exception in thread "Thread-0" java.lang.NullPointerException
at javaapplication4.Test2.run(Test2.java:47)
....
1
Executing & Throwing
Creating new thread
Exception in thread "Thread-1" java.lang.NullPointerException
at javaapplication4.Test2.run(Test2.java:56)
....
1
Code:
代码:
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();
}