当我运行时:
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]);
}
}
它以0的代码退出。发生了什么?我以为ThreadPoolExexcutor在关闭之前等待排队的任务运行。如果是这样,则应该以-1的代码退出。
如果我没有将线程的创建委托给创建线程子类的工厂,那么在主线程以代码0退出之前,我会收到错误通知。
我猜我在创建Thread的子类时遇到了问题,但我不知道在哪里。帮助将不胜感激。
答案 0 :(得分:2)
致电pool#awaitTermination
pool#shutdown
此方法不会等待先前提交的任务完成 执行。使用awaitTermination来做到这一点。
答案 1 :(得分:1)
您对System.exit(0)
的来电将终止正在运行的ExecutorService
。
对shutdown()
的调用是无阻塞的;它只是向执行程序服务发出信号,表示不再提交任何任务,因此可以在已提交的任务完成时清理资源。因为它没有阻止,所以立即调用System.exit(0)
,中止提交的任务。
如果您希望线程等到提交到ExecutorService
的所有任务都已完成,请致电awaitTermination()
,,表明您愿意等多久。