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)