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
的所有任务完成,请调用指示您愿意等待多长时间