ExcecutorService什么时候执行失败?
When does ExcecutorService fails during execution?
根据Executors中关于newFixedThreadPool的文档,我发现
If any thread terminates due to a failure during execution prior to
shutdown, a new one will take its place if needed to execute
subsequent tasks.
虽然我 运行 我的代码,但我检测到我的固定大小的线程池容量为 5 随着时间的推移不断生成线程 pool-1-thread-3212
应该是 pool-1-thread-5 or less
所以我想知道 ExecutorService 什么时候决定它的线程之一失败并启动新线程。
谁能告诉我发生这种情况的原因?
如果你没有正确地实现异常处理,根据你将任务提交给ExeuctorService的方式,线程会死掉。
由于您正在使用 FixedThreadPool
,因此必须维护固定数量的线程以防线程死亡。
如果你使用execute instead of submit,线程会在未处理的异常情况下死亡。
使用execute()
模拟异常和线程死亡的示例代码
导入java.util.concurrent.*;
import java.util.*;
public class ThreadDeath{
public ThreadDeath()
{
System.out.println("creating service");
ExecutorService service = Executors.newFixedThreadPool(2);
for ( int i=0; i < 5; i++){
service.execute(new Runnable(){
public void run(){
int a=4, b = 0;
System.out.println("Thread Name before divide by zero:"+Thread.currentThread().getName());
System.out.println("a and b="+a+":"+b);
System.out.println("a/b:"+(a/b));
}
});
}
service.shutdown();
}
public static void main(String args[]){
ThreadDeath test = new ThreadDeath();
}
}
现在检查输出中的线程名称:
creating service
Thread Name before divide by zero:pool-1-thread-1
Thread Name before divide by zero:pool-1-thread-2
a and b=4:0
a and b=4:0
Exception in thread "pool-1-thread-1" Thread Name before divide by zero:pool-1-thread-3Exception in thread "pool-1-thread-2"
a and b=4:0
Thread Name before divide by zero:pool-1-thread-4
Exception in thread "pool-1-thread-3" a and b=4:0java.lang.ArithmeticException: / by zero
Thread Name before divide by zero:pool-1-thread-5
现在只需在提交 Runnable
任务时将 execute
替换为 submit
。异常将被吞噬,输出如下:(您只能看到两个线程,因为 FixedThreadPool 大小为 2)
creating service
Thread Name before divide by zero:pool-1-thread-1
a and b=4:0
Thread Name before divide by zero:pool-1-thread-2
a and b=4:0
Thread Name before divide by zero:pool-1-thread-1
a and b=4:0
Thread Name before divide by zero:pool-1-thread-2
Thread Name before divide by zero:pool-1-thread-1
a and b=4:0
a and b=4:0
关于线程创建的更多细节,参考这个grepcode link:
private boolean addWorker(Runnable firstTask, boolean core)
根据Executors中关于newFixedThreadPool的文档,我发现
If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.
虽然我 运行 我的代码,但我检测到我的固定大小的线程池容量为 5 随着时间的推移不断生成线程 pool-1-thread-3212
应该是 pool-1-thread-5 or less
所以我想知道 ExecutorService 什么时候决定它的线程之一失败并启动新线程。
谁能告诉我发生这种情况的原因?
如果你没有正确地实现异常处理,根据你将任务提交给ExeuctorService的方式,线程会死掉。
由于您正在使用 FixedThreadPool
,因此必须维护固定数量的线程以防线程死亡。
如果你使用execute instead of submit,线程会在未处理的异常情况下死亡。
使用execute()
导入java.util.concurrent.*;
import java.util.*;
public class ThreadDeath{
public ThreadDeath()
{
System.out.println("creating service");
ExecutorService service = Executors.newFixedThreadPool(2);
for ( int i=0; i < 5; i++){
service.execute(new Runnable(){
public void run(){
int a=4, b = 0;
System.out.println("Thread Name before divide by zero:"+Thread.currentThread().getName());
System.out.println("a and b="+a+":"+b);
System.out.println("a/b:"+(a/b));
}
});
}
service.shutdown();
}
public static void main(String args[]){
ThreadDeath test = new ThreadDeath();
}
}
现在检查输出中的线程名称:
creating service
Thread Name before divide by zero:pool-1-thread-1
Thread Name before divide by zero:pool-1-thread-2
a and b=4:0
a and b=4:0
Exception in thread "pool-1-thread-1" Thread Name before divide by zero:pool-1-thread-3Exception in thread "pool-1-thread-2"
a and b=4:0
Thread Name before divide by zero:pool-1-thread-4
Exception in thread "pool-1-thread-3" a and b=4:0java.lang.ArithmeticException: / by zero
Thread Name before divide by zero:pool-1-thread-5
现在只需在提交 Runnable
任务时将 execute
替换为 submit
。异常将被吞噬,输出如下:(您只能看到两个线程,因为 FixedThreadPool 大小为 2)
creating service
Thread Name before divide by zero:pool-1-thread-1
a and b=4:0
Thread Name before divide by zero:pool-1-thread-2
a and b=4:0
Thread Name before divide by zero:pool-1-thread-1
a and b=4:0
Thread Name before divide by zero:pool-1-thread-2
Thread Name before divide by zero:pool-1-thread-1
a and b=4:0
a and b=4:0
关于线程创建的更多细节,参考这个grepcode link:
private boolean addWorker(Runnable firstTask, boolean core)