Java执行shutdown不终止所有线程?

Java execution shutdown does not terminate all threads?

我创建了以下示例来模拟我遇到的与 ExecutionService 关闭过程相关的情况。似乎它只终止了 3 个线程中的一个...我在 tomcat 服务器上收到错误消息。

public class Test {
static final ExecutorService threadExecutor = Executors.newCachedThreadPool();

static Runnable getTask(final String name) {

    return new Thread() {

        @Override
        public void run() {
            this.setName("Thread-" + name);
            while (true) {
                try {
                    System.out.println(name + " running...[" + this.getName() + "]");
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    System.out.println("InterruptedException..." + this.getName());
throw new Exception(e);
                }
            }

        }
    };
}

public static void main(String... strings) {
    threadExecutor.submit(getTask("Task-1"));
    threadExecutor.submit(getTask("Task-2"));
    threadExecutor.submit(getTask("Task-3"));
    //--
    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            ThreadPoolExecutor tpe = (ThreadPoolExecutor) threadExecutor;
            System.out.println("Active Threads=====>" + tpe.getActiveCount());
            tpe.shutdown();
            try {
                if (!threadExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS)) {
                    System.out.println("Executor did not terminate in the specified time.");
                    List<Runnable> droppedTasks = tpe.shutdownNow();
                    System.out.println("Shutdown thread pool forecibly. " + droppedTasks.size() + " tasks will not be executed.");
                }
                System.out.println("Active Threads=====>" + tpe.getActiveCount());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });

}

}

shutdown() 在线程池中启动关闭进程,但允许当前 运行 任务完成。在您的示例中,任务未完成,因为 while(true).

shutdownNow() 启动关闭并中断当前 运行 线程。但是你的任务又是处理中断的异常和 运行 while(true) 循环。

我认为您可以简单地在您的任务和您调用 threadPoolExecuror.shutdown() 的调用方代码之间共享一个公共布尔值。在任务中使用该布尔值而不是 while(true)