Java ThreadPoolExecutor在关闭前未完全执行线程

Java ThreadPoolExecutor在关闭前未完全执行线程,java,multithreading,Java,Multithreading,当我运行此命令时: import java.util.concurrent.*; public class Foo { static public ExecutorService pool = new ThreadPoolExecutor( 50, 200, 15, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),

当我运行此命令时:

import java.util.concurrent.*;

public class Foo {

    static public ExecutorService pool =
            new ThreadPoolExecutor(
                    50, 200, 15, TimeUnit.SECONDS,
                    new LinkedBlockingQueue<>(),
                    ExLogThread.factory);

    public static void main(String args[]) {
        try {
            pool.execute(Foo::startApp);
            pool.shutdown();
            System.exit(0);
        } catch (Exception ex) {
            for (StackTraceElement elem : ex.getStackTrace())
                System.out.println(elem);
            System.exit(-1);
        }
    }

    static void startApp() {
        throw new RuntimeException();
    }

}

final class ExLogThread extends Thread {

    public static final ThreadFactory factory =
            ExLogThreadFactory.instance;
    private final StackTraceElement[] predecessor;
    private final Runnable r;

    public ExLogThread(Runnable r) {
        super();
        predecessor = Thread.currentThread().getStackTrace();
        this.r = r;
    }

    @Override
    public void run() {
        try {
            r.run();
        } catch (Exception ex) {
            log(ex, predecessor);
            System.exit(-1);
        }
    }

    private static class ExLogThreadFactory
            implements ThreadFactory {

        static public ExLogThreadFactory instance =
                new ExLogThreadFactory();

        @Override
        public Thread newThread(Runnable r) {
            return new ExLogThread(r);
        }

        private ExLogThreadFactory() {}

    }

    private static void log(Exception ex, StackTraceElement[] predecessor) {
        // for example's sake
        for (StackTraceElement elem : ex.getStackTrace())
            System.out.println(elem);
        for (int i = 1; i < predecessor.length; i++)
            System.out.println(predecessor[i]);
    }

}
import java.util.concurrent.*;
公开课Foo{
静态公共服务池=
新线程池执行器(
50,200,15,时间单位,秒,
新建LinkedBlockingQueue(),
ExLogThread.factory);
公共静态void main(字符串参数[]){
试一试{
执行(Foo::startApp);
pool.shutdown();
系统出口(0);
}捕获(例外情况除外){
对于(StackTraceElement元素:例如getStackTrace())
系统输出打印项次(elem);
系统退出(-1);
}
}
静态空隙startApp(){
抛出新的RuntimeException();
}
}
最终类ExLogThread扩展了Thread{
公共静态最终螺纹工厂=
ExLogThreadFactory.instance;
私有最终StackTraceeElement[]前身;
私人终审法院;
公共ExLogThread(可运行的r){
超级();
前置线程=Thread.currentThread().getStackTrace();
这个。r=r;
}
@凌驾
公开募捐{
试一试{
r、 run();
}捕获(例外情况除外){
日志(例如,前身);
系统退出(-1);
}
}
私有静态类ExLogThreadFactory
工具线程工厂{
静态公共ExLogThreadFactory实例=
新的ExLogThreadFactory();
@凌驾
公共线程newThread(可运行的r){
返回新的ExLogThread(r);
}
私有ExLogThreadFactory(){}
}
专用静态无效日志(StackTraceElement[]前置项例外){
//比如说
对于(StackTraceElement元素:例如getStackTrace())
系统输出打印项次(elem);
for(int i=1;i
它正在退出,代码为0。发生什么事?我认为ThreadPoolExexcutor会在关闭前等待队列中的任务运行。如果是这样的话,应该以-1代码退出

如果我没有将线程的创建委托给创建线程子类的工厂,我会在主线程退出之前收到错误通知,代码为0

我猜我在创建线程的子类时出错了,但我不知道在哪里。非常感谢您的帮助。

呼叫
pool#等待终止
呼叫
pool#关机

发件人:

此方法不会等待以前提交的任务完成 执行。使用此选项可以完成此操作


您对
System.exit(0)
的调用将终止正在运行的
ExecutorService

shutdown()
的调用是非阻塞的;它只是向executor服务发出信号,表示不再提交任何任务,因此可以在已提交的任务完成时清理资源。因为它不阻塞,所以会立即调用
System.exit(0)
,中止提交的任务

如果希望线程等待提交给
ExecutorService
的所有任务完成,请调用指示您愿意等待多长时间