Java执行关闭不会终止所有线程?

时间:2015-03-25 22:21:14

标签: java threadpoolexecutor

我创建了以下示例来模仿我遇到的与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();
            }
        }
    });

}

}

1 个答案:

答案 0 :(得分:2)

shutdown()在线程池中启动关闭进程,但允许当前正在运行的任务完成。在您的示例中,由于while(true),任务无法完成。

shutdownNow()启动关闭并中断当前正在运行的线程。但同样,您的任务是处理中断的异常并运行while(true)循环。

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